READ THE DATA
library(dplyr)
Registered S3 method overwritten by 'dplyr':
method from
print.rowwise_df
Attaching package: ‘dplyr’
The following objects are masked from ‘package:stats’:
filter, lag
The following objects are masked from ‘package:base’:
intersect, setdiff, setequal, union
library(data.table)
Registered S3 method overwritten by 'data.table':
method from
print.data.table
data.table 1.12.8 using 4 threads (see ?getDTthreads). Latest news: r-datatable.com
Attaching package: ‘data.table’
The following objects are masked from ‘package:dplyr’:
between, first, last
library(mltools)
chicago_crime <- read.table(file = "chicago_crime_clean.csv", #Name of text file.
sep = ",", #Separation character.
header = TRUE, #If column names are in the first row.
na.strings = "NA", #Character to be marked as missing value.
stringsAsFactors = FALSE)
chicago_crime$location_description <- (gsub(","," ",chicago_crime$location_description))
chicago_crime$description <- gsub(":=","",chicago_crime$description)
chicago_crime$description <- gsub(":","",chicago_crime$description)
chicago_crime$description <- gsub("MANU/POSS. W/","",chicago_crime$description)
chicago_crime$description <- gsub(",","",chicago_crime$description)
#chicago_crime$description <- gsub(".","",chicago_crime$description)
chicago_crime$location_description <- gsub("(E.G. UBER LYFT)","",chicago_crime$location_description)
chicago_crime$location_description <- gsub(",","",chicago_crime$location_description)
#chicago_crime$location_description <- gsub(".","",chicago_crime$location_description)
chicago_crime <- chicago_crime %>%
dplyr::mutate(year = lubridate::year(date),
month = lubridate::month(date),
day = lubridate::day(date))
chicago_crime <- na.omit(chicago_crime)
chicago_crime <- select(chicago_crime,-c(X,unique_key, x_coordinate, y_coordinate, location, domestic, fbi_code, date,year))
chicago_crime$district <- factor(chicago_crime$district)
unique(chicago_crime$primary_type)
[1] "ASSAULT" "OTHER OFFENSE" "NARCOTICS"
[4] "DECEPTIVE PRACTICE" "CRIMINAL TRESPASS" "WEAPONS VIOLATION"
[7] "CRIM SEXUAL ASSAULT" "BURGLARY" "MOTOR VEHICLE THEFT"
[10] "KIDNAPPING" "PUBLIC PEACE VIOLATION" "INTERFERENCE WITH PUBLIC OFFICER"
[13] "BATTERY" "GAMBLING" "ROBBERY"
[16] "OFFENSE INVOLVING CHILDREN" "SEX OFFENSE" "THEFT"
[19] "CONCEALED CARRY LICENSE VIOLATION" "CRIMINAL DAMAGE" "ARSON"
[22] "HOMICIDE" "LIQUOR LAW VIOLATION" "STALKING"
[25] "INTIMIDATION" "PROSTITUTION" "HUMAN TRAFFICKING"
[28] "OBSCENITY" "OTHER NARCOTIC VIOLATION" "PUBLIC INDECENCY"
[31] "NON-CRIMINAL"
head(chicago_crime)
summary(chicago_crime)
case_number block primary_type description location_description arrest district
Length:213687 Length:213687 Length:213687 Length:213687 Length:213687 Length:213687 11 : 14869
Class :character Class :character Class :character Class :character Class :character Class :character 18 : 14243
Mode :character Mode :character Mode :character Mode :character Mode :character Mode :character 1 : 14227
6 : 12717
8 : 12577
12 : 11592
(Other):133462
ward latitude longitude month day
Min. : 1.00 Min. :36.62 Min. :-91.69 Min. : 1.000 Min. : 1.0
1st Qu.:10.00 1st Qu.:41.77 1st Qu.:-87.71 1st Qu.: 4.000 1st Qu.: 8.0
Median :24.00 Median :41.87 Median :-87.66 Median : 7.000 Median :15.0
Mean :23.83 Mean :41.85 Mean :-87.67 Mean : 6.575 Mean :15.5
3rd Qu.:36.00 3rd Qu.:41.91 3rd Qu.:-87.63 3rd Qu.: 9.000 3rd Qu.:23.0
Max. :50.00 Max. :42.02 Max. :-87.52 Max. :12.000 Max. :31.0
Read the training set
library(dplyr)
library(data.table)
library(mltools)
chicago_crime_tr <- read.table(file = "chicago_crime_tr.csv", #Name of text file.
sep = ",", #Separation character.
header = TRUE, #If column names are in the first row.
na.strings = "NA", #Character to be marked as missing value.
stringsAsFactors = FALSE)
chicago_crime_tr$location_description <- (gsub(","," ",chicago_crime_tr$location_description))
chicago_crime_tr$description <- gsub(":=","",chicago_crime_tr$description)
chicago_crime_tr$description <- gsub(":","",chicago_crime_tr$description)
chicago_crime_tr$description <- gsub("MANU/POSS. W/","",chicago_crime_tr$description)
chicago_crime_tr$description <- gsub(",","",chicago_crime_tr$description)
#chicago_crime$description <- gsub(".","",chicago_crime$description)
chicago_crime_tr$location_description <- gsub("(E.G. UBER LYFT)","",chicago_crime_tr$location_description)
chicago_crime_tr$location_description <- gsub(",","",chicago_crime_tr$location_description)
#chicago_crime$location_description <- gsub(".","",chicago_crime$location_description)
chicago_crime_tr <- chicago_crime_tr %>%
dplyr::mutate(year = lubridate::year(date),
month = lubridate::month(date),
day = lubridate::day(date))
chicago_crime_tr <- select(chicago_crime_tr,-c(X,unique_key, x_coordinate, y_coordinate, location, domestic, fbi_code, date,year))
chicago_crime_tr <- na.omit(chicago_crime_tr)
chicago_crime_tr$district <- factor(chicago_crime_tr$district)
unique(chicago_crime_tr$primary_type)
[1] "INTERFERENCE WITH PUBLIC OFFICER" "OTHER OFFENSE" "DECEPTIVE PRACTICE"
[4] "SEX OFFENSE" "CRIM SEXUAL ASSAULT" "BATTERY"
[7] "CRIMINAL TRESPASS" "MOTOR VEHICLE THEFT" "THEFT"
[10] "ASSAULT" "NARCOTICS" "ROBBERY"
[13] "PUBLIC PEACE VIOLATION" "WEAPONS VIOLATION" "STALKING"
[16] "OFFENSE INVOLVING CHILDREN" "ARSON" "BURGLARY"
[19] "CRIMINAL DAMAGE" "HOMICIDE" "INTIMIDATION"
[22] "KIDNAPPING" "HUMAN TRAFFICKING" "PROSTITUTION"
[25] "OBSCENITY" "CONCEALED CARRY LICENSE VIOLATION" "CRIMINAL SEXUAL ASSAULT"
[28] "NON-CRIMINAL" "PUBLIC INDECENCY" "LIQUOR LAW VIOLATION"
[31] "GAMBLING" "OTHER NARCOTIC VIOLATION" "NON - CRIMINAL"
[34] "NON-CRIMINAL (SUBJECT SPECIFIED)"
head(chicago_crime_tr)
summary(chicago_crime_tr)
case_number block primary_type description location_description arrest district
Length:666666 Length:666666 Length:666666 Length:666666 Length:666666 Length:666666 11 : 45269
Class :character Class :character Class :character Class :character Class :character Class :character 1 : 42067
Mode :character Mode :character Mode :character Mode :character Mode :character Mode :character 18 : 41971
8 : 41215
6 : 37548
12 : 35981
(Other):422615
ward latitude longitude month day
Min. : 1.00 Min. :41.64 Min. :-87.93 Min. : 1.000 Min. : 1.00
1st Qu.:11.00 1st Qu.:41.77 1st Qu.:-87.71 1st Qu.: 4.000 1st Qu.: 8.00
Median :24.00 Median :41.87 Median :-87.66 Median : 7.000 Median :16.00
Mean :23.76 Mean :41.85 Mean :-87.67 Mean : 6.594 Mean :15.72
3rd Qu.:36.00 3rd Qu.:41.91 3rd Qu.:-87.63 3rd Qu.: 9.000 3rd Qu.:23.00
Max. :50.00 Max. :42.02 Max. :-87.52 Max. :12.000 Max. :31.00
chicago_crime_tr$primary_type[chicago_crime_tr$primary_type == "CRIMINAL TRESPASS"] <- "ROBBERY"
chicago_crime_tr$primary_type[chicago_crime_tr$primary_type == "BURGLARY"] <- "ROBBERY"
chicago_crime_tr$primary_type[chicago_crime_tr$primary_type == "MOTOR VEHICLE THEFT"] <- "THEFT"
chicago_crime_tr$primary_type[chicago_crime_tr$primary_type == "HOMICIDE"] <- "VIOLENT CRIME"
chicago_crime_tr$primary_type[chicago_crime_tr$primary_type == "KIDNAPPING"] <- "VIOLENT CRIME"
chicago_crime_tr$primary_type[chicago_crime_tr$primary_type == "BATTERY"] <- "VIOLENT CRIME"
chicago_crime_tr$primary_type[chicago_crime_tr$primary_type == "INTIMIDATION"] <- "VIOLENT CRIME"
chicago_crime_tr$primary_type[chicago_crime_tr$primary_type == "ARSON"] <- "VIOLENT CRIME"
chicago_crime_tr$primary_type[chicago_crime_tr$primary_type == "PROSTITUTION"] <- "SEX OFFENSE"
chicago_crime_tr$primary_type[chicago_crime_tr$primary_type == "CRIM SEXUAL ASSAULT"] <- "SEX OFFENSE"
chicago_crime_tr$primary_type[chicago_crime_tr$primary_type == "OTHER NARCOTIC VIOLATION"] <- "NARCOTICS"
chicago_crime_tr$primary_type <- factor(chicago_crime_tr$primary_type)
chicago_crime_subset_tr <- subset(chicago_crime_tr, primary_type=="ASSAULT" | primary_type == "VIOLENT CRIME" | primary_type == "THEFT" | primary_type=="NARCOTICS" | primary_type == "WEAPONS VIOLATION" | primary_type=="ROBBERY" | primary_type == "CRIMINAL DAMAGE" | primary_type == "DECEPTIVE PRACTICE" )
chicago_crime_subset_tr$primary_type <- factor(chicago_crime_subset_tr$primary_type)
chicago_crime_subset_tr <- na.omit(chicago_crime_subset_tr)
library(DataExplorer)
Registered S3 methods overwritten by 'htmltools':
method from
print.html tools:rstudio
print.shiny.tag tools:rstudio
print.shiny.tag.list tools:rstudio
Registered S3 method overwritten by 'htmlwidgets':
method from
print.htmlwidget tools:rstudio
plot_str(chicago_crime_subset_tr)
plot_missing(chicago_crime_subset_tr)

#plot_histogram(chicago_crime_subset)
#plot_density(chicago_crime_subset)
#plot_correlation(chicago_numeric, type = 'continuous')
chicago_crime_subset_tr$month <- as.factor(chicago_crime_subset_tr$month)
plot_bar(chicago_crime_subset_tr)
4 columns ignored with more than 50 categories.
case_number: 610345 categories
block: 31746 categories
description: 210 categories
location_description: 162 categories

EXPLORATORY ANALYSIS
library(tidyverse)
Registered S3 methods overwritten by 'dbplyr':
method from
print.tbl_lazy
print.tbl_sql
[30m── [1mAttaching packages[22m ──────────────────────────────────────────────────────────────────────────────────────────────── tidyverse 1.3.0 ──[39m
[30m[32m✓[30m [34mggplot2[30m 3.2.1 [32m✓[30m [34mpurrr [30m 0.3.3
[32m✓[30m [34mtibble [30m 2.1.3 [32m✓[30m [34mstringr[30m 1.4.0
[32m✓[30m [34mtidyr [30m 1.0.2 [32m✓[30m [34mforcats[30m 0.4.0
[32m✓[30m [34mreadr [30m 1.3.1 [39m
[30m── [1mConflicts[22m ─────────────────────────────────────────────────────────────────────────────────────────────────── tidyverse_conflicts() ──
[31mx[30m [34mdata.table[30m::[32mbetween()[30m masks [34mdplyr[30m::between()
[31mx[30m [34mdplyr[30m::[32mfilter()[30m masks [34mstats[30m::filter()
[31mx[30m [34mdata.table[30m::[32mfirst()[30m masks [34mdplyr[30m::first()
[31mx[30m [34mdplyr[30m::[32mlag()[30m masks [34mstats[30m::lag()
[31mx[30m [34mdata.table[30m::[32mlast()[30m masks [34mdplyr[30m::last()
[31mx[30m [34mtidyr[30m::[32mreplace_na()[30m masks [34mmltools[30m::replace_na()
[31mx[30m [34mpurrr[30m::[32mtranspose()[30m masks [34mdata.table[30m::transpose()[39m
ggplot(data = chicago_crime) +
geom_bar(mapping = aes(x = primary_type)) +
theme(axis.text.x = element_text(angle = 90, hjust = 1))

chicago_crime %>%
count(primary_type)
ggplot(data = chicago_crime) +
geom_bar(mapping = aes(x = district)) +
theme(axis.text.x = element_text(hjust = 1))

chicago_crime %>%
count(district)
ggplot(data = chicago_crime) +
geom_bar(mapping = aes(x = arrest)) +
theme(axis.text.x = element_text(hjust = 1))

chicago_crime %>%
count(arrest)
#chicago_crime$primary_type <- as.character(junk$nm)
chicago_crime$primary_type[chicago_crime$primary_type == "CRIMINAL TRESPASS"] <- "ROBBERY"
chicago_crime$primary_type[chicago_crime$primary_type == "BURGLARY"] <- "ROBBERY"
chicago_crime$primary_type[chicago_crime$primary_type == "MOTOR VEHICLE THEFT"] <- "THEFT"
chicago_crime$primary_type[chicago_crime$primary_type == "HOMICIDE"] <- "VIOLENT CRIME"
chicago_crime$primary_type[chicago_crime$primary_type == "KIDNAPPING"] <- "VIOLENT CRIME"
chicago_crime$primary_type[chicago_crime$primary_type == "BATTERY"] <- "VIOLENT CRIME"
chicago_crime$primary_type[chicago_crime$primary_type == "INTIMIDATION"] <- "VIOLENT CRIME"
chicago_crime$primary_type[chicago_crime$primary_type == "ARSON"] <- "VIOLENT CRIME"
chicago_crime$primary_type[chicago_crime$primary_type == "PROSTITUTION"] <- "SEX OFFENSE"
chicago_crime$primary_type[chicago_crime$primary_type == "CRIM SEXUAL ASSAULT"] <- "SEX OFFENSE"
chicago_crime$primary_type[chicago_crime$primary_type == "OTHER NARCOTIC VIOLATION"] <- "NARCOTICS"
chicago_crime$primary_type <- factor(chicago_crime$primary_type)
ggplot(data = chicago_crime) +
geom_bar(mapping = aes(x = primary_type)) +
theme(axis.text.x = element_text(angle = 90, hjust = 1))

chicago_crime %>%
count(primary_type)
chicago_crime_subset <- subset(chicago_crime, primary_type=="ASSAULT" | primary_type == "VIOLENT CRIME" | primary_type == "THEFT" | primary_type=="NARCOTICS" | primary_type == "WEAPONS VIOLATION" | primary_type=="ROBBERY" | primary_type == "CRIMINAL DAMAGE" | primary_type == "DECEPTIVE PRACTICE" )
chicago_crime_subset$primary_type <- factor(chicago_crime_subset$primary_type)
ggplot(data = chicago_crime_subset) +
geom_bar(mapping = aes(x = primary_type)) +
theme(axis.text.x = element_text(angle = 90, hjust = 1))

ggplot(data = chicago_crime_subset) +
geom_count(mapping = aes(x = primary_type, y = district)) +
theme(axis.text.x = element_text(angle = 90, hjust = 1))

ggplot(data = chicago_crime_subset) +
geom_count(mapping = aes(x = arrest, y = primary_type)) +
theme(axis.text.x = element_text(angle = 90, hjust = 1))

ggplot(data = chicago_crime_subset) +
geom_count(mapping = aes(x = arrest, y = district)) +
theme(axis.text.x = element_text(angle = 90, hjust = 1))

EXPLORATORY ANALYSIS BY CRIME
assault <- subset(chicago_crime_subset, primary_type=="ASSAULT")
violent_crime <- subset(chicago_crime_subset, primary_type=="VIOLENT CRIME")
theft <- subset(chicago_crime_subset, primary_type=="THEFT")
narcotics <- subset(chicago_crime_subset, primary_type=="NARCOTICS")
weapons_violation <- subset(chicago_crime_subset, primary_type=="WEAPONS VIOLATION")
robbery <- subset(chicago_crime_subset, primary_type=="ROBBERY")
criminal_damage <- subset(chicago_crime_subset, primary_type=="CRIMINAL DAMAGE")
deceptive_practice <- subset(chicago_crime_subset, primary_type=="DECEPTIVE PRACTICE")
assault_tr <- subset(chicago_crime_subset_tr, primary_type=="ASSAULT")
violent_tr_crime <- subset(chicago_crime_subset_tr, primary_type=="VIOLENT CRIME")
theft_tr <- subset(chicago_crime_subset_tr, primary_type=="THEFT")
narcotics_tr <- subset(chicago_crime_subset_tr, primary_type=="NARCOTICS")
weapons_violation_tr <- subset(chicago_crime_subset_tr, primary_type=="WEAPONS VIOLATION")
robbery_tr <- subset(chicago_crime_subset_tr, primary_type=="ROBBERY")
criminal_damage_tr <- subset(chicago_crime_subset_tr, primary_type=="CRIMINAL DAMAGE")
deceptive_practice_tr <- subset(chicago_crime_subset_tr, primary_type=="DECEPTIVE PRACTICE")
DISTRICTS
library(sqldf)
Loading required package: gsubfn
Loading required package: proto
unable to load shared object '/Library/Frameworks/R.framework/Resources/modules//R_X11.so':
dlopen(/Library/Frameworks/R.framework/Resources/modules//R_X11.so, 6): Library not loaded: /opt/X11/lib/libSM.6.dylib
Referenced from: /Library/Frameworks/R.framework/Resources/modules//R_X11.so
Reason: image not foundCould not load tcltk. Will use slower R code instead.
Loading required package: RSQLite
districts_true <- sqldf('SELECT district, AVG(latitude) as avg_latitude,AVG(longitude) as avg_longitude, count(*) as arrest FROM chicago_crime_subset WHERE arrest LIKE "True" GROUP BY district ORDER BY district')
districts_false <- sqldf('SELECT district, AVG(latitude) as avg_latitude,AVG(longitude) as avg_longitude, count(*) as no_arrest FROM chicago_crime_subset WHERE arrest LIKE "False" GROUP BY district ORDER BY district')
districts_true$arrest <- as.numeric(districts_true$arrest)
districts_false$no_arrest <- as.numeric(districts_false$no_arrest)
districts_true
districts_false
police_districts <- read.table(file = "Police_Stations.csv", #Name of text file.
sep = ",", #Separation character.
header = TRUE, #If column names are in the first row.
na.strings = "NA", #Character to be marked as missing value.
stringsAsFactors = FALSE)
police_districts
police_districts$DISTRICT[police_districts$DISTRICT == "Headquarters"] <- "0"
police_districts$DISTRICT <- as.factor(police_districts$DISTRICT)
districts <- sqldf('SELECT DISTRICT as district, LATITUDE as latitude,LONGITUDE as longitude FROM police_districts')
arrest_percentage <- data.frame('District' = districts_false$district, 'PctArrest' = districts_true$arrest/(districts_true$arrest + districts_false$no_arrest), 'Crimes' = (districts_true$arrest + districts_false$no_arrest))
arrest_percentage
ggplot(data = arrest_percentage) +
geom_col(mapping = aes(x = District, y = Crimes)) +
geom_line(aes(x = District, y = PctArrest*10000, group = 1), color = "yellow") +
scale_y_continuous(sec.axis = sec_axis(~./10000, name = "PctArrest")) +
theme(axis.text.x = element_text(hjust = 1))

## INITIALIZE
library("leaflet")
library("data.table")
library("sp")
library("rgdal")
rgdal: version: 1.4-8, (SVN revision 845)
Geospatial Data Abstraction Library extensions to R successfully loaded
Loaded GDAL runtime: GDAL 2.4.2, released 2019/06/28
Path to GDAL shared files: /Library/Frameworks/R.framework/Versions/3.6/Resources/library/rgdal/gdal
GDAL binary built with GEOS: FALSE
Loaded PROJ.4 runtime: Rel. 5.2.0, September 15th, 2018, [PJ_VERSION: 520]
Path to PROJ.4 shared files: /Library/Frameworks/R.framework/Versions/3.6/Resources/library/rgdal/proj
Linking to sp version: 1.3-2
# library("maptools")
library("KernSmooth")
KernSmooth 2.23 loaded
Copyright M. P. Wand 1997-2009
setDT(districts_false)
#devtools::install_github("dkahle/ggmap", ref = "tidyup", force = TRUE)
library(ggmap)
Google's Terms of Service: https://cloud.google.com/maps-platform/terms/.
Please cite ggmap if you use it! See citation("ggmap") for details.
chicago <- get_stamenmap(bbox = c(left = -88.0225, bottom = 41.5949,
right = -87.2713, top = 42.0677),
zoom = 11)
Source : http://tile.stamen.com/terrain/11/523/759.png
Source : http://tile.stamen.com/terrain/11/524/759.png
Source : http://tile.stamen.com/terrain/11/525/759.png
Source : http://tile.stamen.com/terrain/11/526/759.png
Source : http://tile.stamen.com/terrain/11/527/759.png
Source : http://tile.stamen.com/terrain/11/523/760.png
Source : http://tile.stamen.com/terrain/11/524/760.png
Source : http://tile.stamen.com/terrain/11/525/760.png
Source : http://tile.stamen.com/terrain/11/526/760.png
Source : http://tile.stamen.com/terrain/11/527/760.png
Source : http://tile.stamen.com/terrain/11/523/761.png
Source : http://tile.stamen.com/terrain/11/524/761.png
Source : http://tile.stamen.com/terrain/11/525/761.png
Source : http://tile.stamen.com/terrain/11/526/761.png
Source : http://tile.stamen.com/terrain/11/527/761.png
Source : http://tile.stamen.com/terrain/11/523/762.png
Source : http://tile.stamen.com/terrain/11/524/762.png
Source : http://tile.stamen.com/terrain/11/525/762.png
Source : http://tile.stamen.com/terrain/11/526/762.png
Source : http://tile.stamen.com/terrain/11/527/762.png
Source : http://tile.stamen.com/terrain/11/523/763.png
Source : http://tile.stamen.com/terrain/11/524/763.png
Source : http://tile.stamen.com/terrain/11/525/763.png
Source : http://tile.stamen.com/terrain/11/526/763.png
Source : http://tile.stamen.com/terrain/11/527/763.png
ggmap(chicago) +
geom_text(aes(x = longitude, y = latitude, label = district), data = districts)

library(ggmap)
chicago <- get_stamenmap(bbox = c(left = -88.0225, bottom = 41.5949,
right = -87.2713, top = 42.0677),
zoom = 11)
ggmap(chicago) +
geom_text(aes(x = LONGITUDE, y = LATITUDE, label = DISTRICT), data = police_districts)

ggplot(data = assault) +
geom_bar(mapping = aes(x = district)) +
theme(axis.text.x = element_text(hjust = 1)) +
ggtitle("ASSAULT BY DISTRICT")

ggplot(data = theft) +
geom_bar(mapping = aes(x = district)) +
theme(axis.text.x = element_text(hjust = 1)) +
ggtitle("THEFTS BY DISTRICT")

ggplot(data = violent_crime) +
geom_bar(mapping = aes(x = district)) +
theme(axis.text.x = element_text(hjust = 1)) +
ggtitle("VIOLENT CRIMES BY DISTRICT")

ggplot(data = narcotics) +
geom_bar(mapping = aes(x = district)) +
theme(axis.text.x = element_text(hjust = 1)) +
ggtitle("NARCOTIC CRIMES BY DISTRICT")

ggplot(data = weapons_violation) +
geom_bar(mapping = aes(x = district)) +
theme(axis.text.x = element_text(hjust = 1)) +
ggtitle("WEAPON-RELATED CRIMES BY DISTRICT")

ggplot(data = robbery) +
geom_bar(mapping = aes(x = district)) +
theme(axis.text.x = element_text(hjust = 1)) +
ggtitle("ROBBERIES BY DISTRICT")

ggplot(data = criminal_damage) +
geom_bar(mapping = aes(x = district)) +
theme(axis.text.x = element_text(hjust = 1)) +
ggtitle("CRIMINAL DAMAGE CRIMES BY DISTRICT")

ggplot(data = deceptive_practice) +
geom_bar(mapping = aes(x = district)) +
theme(axis.text.x = element_text(hjust = 1)) +
ggtitle("DECEPTIVE PRACTICE CRIMES BY DISTRICT")

library(ggplot2)
ggplot(data = chicago_crime_subset, aes(x=primary_type, y=district, fill=arrest)) +
geom_tile() +
theme(axis.text.x = element_text(angle = 90, hjust = 1))

# Correlation
library(ggplot2)
ggplot(chicago_crime_subset,aes(x=district,y=primary_type,color=arrest))+geom_point(alpha=0.5)

Association Rules
chicago_crime_subset_2 <- subset(chicago_crime_subset, select=-c(case_number,block,ward,description,day,month,latitude,longitude))
chicago_crime_subset_2 <- subset(chicago_crime_subset_2, select=-c(location_description))
write.csv(chicago_crime_subset_2,"chicago_crime_AR.csv", quote = FALSE, row.names = FALSE)
library(arules)
Loading required package: Matrix
Attaching package: ‘Matrix’
The following objects are masked from ‘package:tidyr’:
expand, pack, unpack
Attaching package: ‘arules’
The following object is masked from ‘package:dplyr’:
recode
The following objects are masked from ‘package:base’:
abbreviate, write
crime_transactions <- read.transactions("chicago_crime_AR.csv", sep=",")
#deceptive_practice_2 <- subset(deceptive_practice, select=-c(case_number,block,ward,description,day,month,latitude,longitude))
#write.csv(deceptive_practice_2,"deceptive_practice.csv", quote = FALSE, row.names = FALSE)
#dp_transactions <- read.transactions("deceptive_practice.csv", sep=",")
if (!require("RColorBrewer")) {
# install color package of R
install.packages("RColorBrewer")
#include library RColorBrewer
library(RColorBrewer)
}
Loading required package: RColorBrewer
itemFrequencyPlot(crime_transactions,topN=20,type="absolute",
col=brewer.pal(8,'Pastel2'),
main="Absolute Item Frequency Plot")

Reglas de Asociacion General
# Rule GENERATION
association.rules.clean <- apriori(crime_transactions, parameter = list(supp=0.001, conf=0.7))
Apriori
Parameter specification:
Algorithmic control:
Absolute minimum support count: 194
set item appearances ...[0 item(s)] done [0.00s].
set transactions ...[36 item(s), 194542 transaction(s)] done [0.04s].
sorting and recoding items ... [32 item(s)] done [0.00s].
creating transaction tree ... done [0.04s].
checking subsets of size 1 2 3 done [0.00s].
writing ... [179 rule(s)] done [0.00s].
creating S4 object ... done [0.02s].
subset.rules.clean <- which(colSums(is.subset(association.rules.clean, association.rules.clean)) > 1)
subset.association.rules.clean. <- association.rules.clean[-subset.rules.clean]
inspect(subset.association.rules.clean.)
rules_by_count <- sort(association.rules.clean, by = "count")
rules_by_conf <- sort(association.rules.clean, by = "confidence")
rules_by_supp <- sort(association.rules.clean, by = "lift")
inspect(rules_by_count)
inspect(rules_by_conf)
inspect(rules_by_supp)
# Rule GENERATION
assault.association.rules <- apriori(crime_transactions, parameter =
list(supp=0.001, conf=0.1),
appearance = list(default="lhs",rhs="ASSAULT"))
Apriori
Parameter specification:
Algorithmic control:
Absolute minimum support count: 194
set item appearances ...[1 item(s)] done [0.00s].
set transactions ...[36 item(s), 194542 transaction(s)] done [0.04s].
sorting and recoding items ... [32 item(s)] done [0.00s].
creating transaction tree ... done [0.05s].
checking subsets of size 1 2 3 done [0.00s].
writing ... [7 rule(s)] done [0.00s].
creating S4 object ... done [0.02s].
# Borrar reglas redundantes
assault.subset.rules <- which(colSums(is.subset(assault.association.rules, assault.association.rules)) > 1) # get subset rules in vector
assault.subset.association.rules. <- assault.association.rules[-assault.subset.rules] # remove subset rules.
inspect(assault.subset.association.rules.)
as_by_count <- sort(assault.association.rules, by = "count")
as_by_conf <- sort(assault.association.rules, by = "confidence")
#dp_by_supp <- sort(dp.subset.association.rules., by = "support")
inspect(as_by_count)
inspect(as_by_conf)
#inspect(dp_by_supp)
# Rule GENERATION
cd.association.rules <- apriori(crime_transactions, parameter =
list(supp=0.001, conf=0.1),
appearance = list(default="lhs",rhs="CRIMINAL DAMAGE"))
Apriori
Parameter specification:
Algorithmic control:
Absolute minimum support count: 194
set item appearances ...[1 item(s)] done [0.00s].
set transactions ...[36 item(s), 194542 transaction(s)] done [0.04s].
sorting and recoding items ... [32 item(s)] done [0.00s].
creating transaction tree ... done [0.04s].
checking subsets of size 1 2 3 done [0.00s].
writing ... [40 rule(s)] done [0.00s].
creating S4 object ... done [0.02s].
# Borrar reglas redundantes
cd.subset.rules <- which(colSums(is.subset(cd.association.rules, cd.association.rules)) > 1) # get subset rules in vector
cd.subset.association.rules. <- cd.association.rules[-cd.subset.rules] # remove subset rules.
inspect(cd.association.rules)
cd_by_count <- sort(cd.association.rules, by = "count")
cd_by_conf <- sort(cd.association.rules, by = "confidence")
#dp_by_supp <- sort(dp.subset.association.rules., by = "support")
inspect(cd_by_count)
inspect(cd_by_conf)
#inspect(dp_by_supp)
# Rule GENERATION
dp.association.rules <- apriori(crime_transactions, parameter =
list(supp=0.001, conf=0.1),
appearance = list(default="lhs",rhs="DECEPTIVE PRACTICE"))
Apriori
Parameter specification:
Algorithmic control:
Absolute minimum support count: 194
set item appearances ...[1 item(s)] done [0.00s].
set transactions ...[36 item(s), 194542 transaction(s)] done [0.04s].
sorting and recoding items ... [32 item(s)] done [0.00s].
creating transaction tree ... done [0.04s].
checking subsets of size 1 2 3 done [0.00s].
writing ... [19 rule(s)] done [0.00s].
creating S4 object ... done [0.05s].
# Borrar reglas redundantes
dp.subset.rules <- which(colSums(is.subset(dp.association.rules, dp.association.rules)) > 1) # get subset rules in vector
dp.subset.association.rules. <- dp.association.rules[-dp.subset.rules] # remove subset rules.
inspect(dp.subset.association.rules.)
dp_by_count <- sort(dp.subset.association.rules., by = "count")
dp_by_conf <- sort(dp.subset.association.rules., by = "confidence")
#dp_by_supp <- sort(dp.subset.association.rules., by = "support")
inspect(dp_by_count)
inspect(dp_by_conf)
#inspect(dp_by_supp)
narcotics_clean.association.rules <- apriori(crime_transactions, parameter =
list(supp=0.001, conf=0.1),
appearance = list(default="lhs",rhs="NARCOTICS"))
Apriori
Parameter specification:
Algorithmic control:
Absolute minimum support count: 194
set item appearances ...[1 item(s)] done [0.00s].
set transactions ...[36 item(s), 194542 transaction(s)] done [0.04s].
sorting and recoding items ... [32 item(s)] done [0.00s].
creating transaction tree ... done [0.04s].
checking subsets of size 1 2 3 done [0.00s].
writing ... [18 rule(s)] done [0.00s].
creating S4 object ... done [0.02s].
# Borrar reglas redundantes
narcotics_clean.subset.rules <- which(colSums(is.subset(narcotics_clean.association.rules, narcotics_clean.association.rules)) > 1) # get subset rules in vector
narcotics_clean.subset.association.rules. <- narcotics_clean.association.rules[-narcotics_clean.subset.rules] # remove subset rules.
inspect(narcotics_clean.subset.association.rules.)
narc_by_count <- sort(narcotics_clean.association.rules, by = "count")
narc_by_conf <- sort(narcotics_clean.association.rules, by = "confidence")
#dp_by_supp <- sort(dp.subset.association.rules., by = "support")
inspect(narc_by_count)
inspect(narc_by_conf)
#inspect(dp_by_supp)
robbery.association.rules <- apriori(crime_transactions, parameter =
list(supp=0.001, conf=0.15),
appearance = list(default="lhs",rhs="ROBBERY"))
Apriori
Parameter specification:
Algorithmic control:
Absolute minimum support count: 194
set item appearances ...[1 item(s)] done [0.00s].
set transactions ...[36 item(s), 194542 transaction(s)] done [0.03s].
sorting and recoding items ... [32 item(s)] done [0.00s].
creating transaction tree ... done [0.05s].
checking subsets of size 1 2 3 done [0.00s].
writing ... [11 rule(s)] done [0.00s].
creating S4 object ... done [0.02s].
# Borrar reglas redundantes
robbery.subset.rules <- which(colSums(is.subset(robbery.association.rules, robbery.association.rules)) > 1)
robbery.subset.association.rules. <- robbery.association.rules[-robbery.subset.rules] # remove subset rules.
inspect(robbery.association.rules)
rob_by_count <- sort(robbery.association.rules, by = "count")
rob_by_conf <- sort(robbery.association.rules, by = "confidence")
#dp_by_supp <- sort(dp.subset.association.rules., by = "support")
inspect(rob_by_count)
inspect(rob_by_conf)
#inspect(dp_by_supp)
theft.association.rules <- apriori(crime_transactions, parameter =
list(supp=0.005, conf=0.5),
appearance = list(default="lhs",rhs="THEFT"))
Apriori
Parameter specification:
Algorithmic control:
Absolute minimum support count: 972
set item appearances ...[1 item(s)] done [0.00s].
set transactions ...[36 item(s), 194542 transaction(s)] done [0.04s].
sorting and recoding items ... [32 item(s)] done [0.00s].
creating transaction tree ... done [0.05s].
checking subsets of size 1 2 3 done [0.00s].
writing ... [4 rule(s)] done [0.00s].
creating S4 object ... done [0.02s].
# Borrar reglas redundantes
theft.subset.rules <- which(colSums(is.subset(theft.association.rules, theft.association.rules)) > 1)
theft.subset.association.rules. <- theft.association.rules[-theft.subset.rules] # remove subset rules.
inspect(theft.subset.association.rules.)
theft_by_count <- sort(theft.association.rules, by = "count")
theft_by_conf <- sort(theft.association.rules, by = "confidence")
#dp_by_supp <- sort(dp.subset.association.rules., by = "support")
inspect(theft_by_count)
inspect(theft_by_conf)
#inspect(dp_by_supp)
vc.association.rules <- apriori(crime_transactions, parameter =
list(supp=0.001, conf=0.15),
appearance = list(default="lhs",rhs="VIOLENT CRIME"))
Apriori
Parameter specification:
Algorithmic control:
Absolute minimum support count: 194
set item appearances ...[1 item(s)] done [0.00s].
set transactions ...[36 item(s), 194542 transaction(s)] done [0.03s].
sorting and recoding items ... [32 item(s)] done [0.00s].
creating transaction tree ... done [0.05s].
checking subsets of size 1 2 3 done [0.00s].
writing ... [21 rule(s)] done [0.00s].
creating S4 object ... done [0.02s].
# Borrar reglas redundantes
vc.subset.rules <- which(colSums(is.subset(vc.association.rules, vc.association.rules)) > 1) # get subset rules in
vc.subset.association.rules. <- vc.association.rules[-vc.subset.rules] # remove subset rules.
inspect(vc.subset.association.rules.)
vc_by_count <- sort(vc.association.rules, by = "count")
vc_by_conf <- sort(vc.association.rules, by = "confidence")
#vc_by_supp <- sort(vc.subset.association.rules., by = "support")
inspect(vc_by_count)
inspect(vc_by_conf)
#inspect(wv_by_supp)
wv.association.rules <- apriori(crime_transactions,parameter =
list(supp=0.001, conf=0.1),
appearance = list(default="lhs",rhs="WEAPONS VIOLATION"))
Apriori
Parameter specification:
Algorithmic control:
Absolute minimum support count: 194
set item appearances ...[1 item(s)] done [0.00s].
set transactions ...[36 item(s), 194542 transaction(s)] done [0.03s].
sorting and recoding items ... [32 item(s)] done [0.00s].
creating transaction tree ... done [0.05s].
checking subsets of size 1 2 3 done [0.00s].
writing ... [8 rule(s)] done [0.00s].
creating S4 object ... done [0.02s].
# Borrar reglas redundantes
wv.subset.rules <- which(colSums(is.subset(wv.association.rules, wv.association.rules)) > 1) # get subset rules in
wv.subset.association.rules. <- wv.association.rules[-wv.subset.rules] # remove subset rules.
inspect(wv.subset.association.rules.)
wv_by_count <- sort(wv.association.rules, by = "count")
wv_by_conf <- sort(wv.association.rules, by = "confidence")
#wv_by_supp <- sort(wv.subset.association.rules., by = "support")
inspect(wv_by_count)
inspect(wv_by_conf)
#inspect(wv_by_supp)
true.association.rules <- apriori(crime_transactions,parameter =
list(supp=0.001, conf=0.5),
appearance = list(default="lhs",rhs="True"))
Apriori
Parameter specification:
Algorithmic control:
Absolute minimum support count: 194
set item appearances ...[1 item(s)] done [0.00s].
set transactions ...[36 item(s), 194542 transaction(s)] done [0.04s].
sorting and recoding items ... [32 item(s)] done [0.00s].
creating transaction tree ... done [0.05s].
checking subsets of size 1 2 3 done [0.00s].
writing ... [24 rule(s)] done [0.00s].
creating S4 object ... done [0.02s].
# Borrar reglas redundantes
true.subset.rules <- which(colSums(is.subset(true.association.rules, true.association.rules)) > 1) # get subset rules in
true.subset.association.rules. <- true.association.rules[-true.subset.rules] # remove subset rules.
inspect(true.subset.association.rules.)
t_by_count <- sort(true.subset.association.rules., by = "count")
t_by_conf <- sort(true.subset.association.rules., by = "confidence")
#wv_by_supp <- sort(wv.subset.association.rules., by = "support")
inspect(t_by_count)
inspect(t_by_conf)
#inspect(wv_by_supp)
false.association.rules <- apriori(crime_transactions,parameter =
list(supp=0.001, conf=0.8),
appearance = list(default="lhs",rhs="False"))
Apriori
Parameter specification:
Algorithmic control:
Absolute minimum support count: 194
set item appearances ...[1 item(s)] done [0.00s].
set transactions ...[36 item(s), 194542 transaction(s)] done [0.04s].
sorting and recoding items ... [32 item(s)] done [0.00s].
creating transaction tree ... done [0.05s].
checking subsets of size 1 2 3 done [0.00s].
writing ... [125 rule(s)] done [0.00s].
creating S4 object ... done [0.02s].
# Borrar reglas redundantes
false.subset.rules <- which(colSums(is.subset(false.association.rules, false.association.rules)) > 1) # get subset rules in
false.subset.association.rules. <- false.association.rules[-false.subset.rules] # remove subset rules.
inspect(false.subset.association.rules.)
f_by_count <- sort(false.association.rules, by = "count")
f_by_conf <- sort(false.association.rules, by = "confidence")
#wv_by_supp <- sort(wv.subset.association.rules., by = "support")
inspect(f_by_count)
inspect(f_by_conf)
#inspect(wv_by_supp)
ocho.association.rules <- apriori(crime_transactions,parameter =
list(supp=0.0001, conf=0.01),
appearance = list(default="lhs",rhs="8"))
Apriori
Parameter specification:
Algorithmic control:
Absolute minimum support count: 19
set item appearances ...[1 item(s)] done [0.00s].
set transactions ...[36 item(s), 194542 transaction(s)] done [0.03s].
sorting and recoding items ... [32 item(s)] done [0.00s].
creating transaction tree ... done [0.04s].
checking subsets of size 1 2 3 done [0.00s].
writing ... [26 rule(s)] done [0.00s].
creating S4 object ... done [0.02s].
# Borrar reglas redundantes
ocho.subset.rules <- which(colSums(is.subset(ocho.association.rules, ocho.association.rules)) > 1) # get subset rules in
ocho.subset.association.rules. <- ocho.association.rules[-ocho.subset.rules] # remove subset rules.
inspect(ocho.subset.association.rules.)
ocho_by_count <- sort(ocho.association.rules, by = "count")
ocho_by_conf <- sort(ocho.association.rules, by = "confidence")
#wv_by_supp <- sort(wv.subset.association.rules., by = "support")
inspect(ocho_by_count)
inspect(ocho_by_conf)
#inspect(wv_by_supp)
## GRAFICOS
## Dataset Entero
library(arulesViz)
Loading required package: grid
Registered S3 method overwritten by 'seriation':
method from
reorder.hclust gclus
# Filter rules with confidence greater than 0.4 or 40%
subRules<-association.rules.clean[quality(association.rules.clean)$confidence>0.7]
#Plot SubRules
plot(subRules,method="two-key plot")

## Seleccionamos un numero limitado de reglas en el dataset limpio
top10subRules <- head(subRules, n = 25, by = "confidence")
# Now, plot an interactive graph:
#Note: You can make all your plots interactive using engine=htmlwidget parameter in plot
plot(top10subRules, method = "graph", engine = "htmlwidget")
## Individual Rule Representation Dataset Limpio
# Filter top 20 rules with highest lift
subRules2<-head(subRules, n=25, by="confidence")
plot(subRules2, method="paracoord")

#Plot SubRules
plot(assault.subset.association.rules.,method="two-key plot")

## Seleccionamos un numero limitado de reglas en el dataset limpio
top10subRules <- head(assault.subset.association.rules., n = 20, by = "confidence")
inspect(top10subRules)
# Now, plot an interactive graph:
#Note: You can make all your plots interactive using engine=htmlwidget parameter in plot
plot(assault.subset.association.rules., method = "graph", engine = "htmlwidget")
## Individual Rule Representation Dataset Limpio
# Filter top 20 rules with highest lift
subRules2<-head(assault.subset.association.rules., n=20, by="confidence")
plot(top10subRules, method="paracoord")

#Plot SubRules
plot(cd.association.rules,method="two-key plot")

subRules_cd<-cd.association.rules[quality(cd.association.rules)$confidence>0.2]
## Seleccionamos un numero limitado de reglas en el dataset limpio
top10subRules <- head(cd.association.rules, n = 10, by = "confidence")
inspect(top10subRules)
# Now, plot an interactive graph:
#Note: You can make all your plots interactive using engine=htmlwidget parameter in plot
plot(subRules_cd, method = "graph", engine = "htmlwidget")
## Individual Rule Representation Dataset Limpio
# Filter top 20 rules with highest lift
subRules2<-head(subRules_cd, n=25, by="confidence")
plot(top10subRules, method="paracoord")

#Plot SubRules
plot(dp.association.rules,method="two-key plot")

subRules_dp<-dp.association.rules[quality(dp.association.rules)$confidence>0.1]
## Seleccionamos un numero limitado de reglas en el dataset limpio
top10subRules <- head(dp.association.rules, n = 10, by = "count")
# Now, plot an interactive graph:
#Note: You can make all your plots interactive using engine=htmlwidget parameter in plot
plot(subRules_dp, method = "graph", engine = "htmlwidget")
## Individual Rule Representation Dataset Limpio
# Filter top 20 rules with highest lift
subRules2<-head(subRules_dp, n=25, by="count")
plot(subRules_dp, method="paracoord")

#Plot SubRules
plot(narcotics_clean.association.rules,method="two-key plot")

subRules_narcotics<-narcotics_clean.association.rules[quality(narcotics_clean.association.rules)$confidence>0.6]
## Seleccionamos un numero limitado de reglas en el dataset limpio
top10subRules <- head(narcotics_clean.association.rules, n = 10, by = "confidence")
# Now, plot an interactive graph:
#Note: You can make all your plots interactive using engine=htmlwidget parameter in plot
plot(subRules_narcotics, method = "graph", engine = "htmlwidget")
## Individual Rule Representation Dataset Limpio
# Filter top 20 rules with highest lift
subRules2<-head(subRules_narcotics, n=25, by="confidence")
plot(subRules_narcotics, method="paracoord")

#Plot SubRules
plot(robbery.association.rules,method="two-key plot")

subRules_robbery<-robbery.association.rules[quality(robbery.association.rules)$confidence>0.15]
## Seleccionamos un numero limitado de reglas en el dataset limpio
top10subRules <- head(robbery.association.rules, n = 10, by = "confidence")
inspect(top10subRules)
# Now, plot an interactive graph:
#Note: You can make all your plots interactive using engine=htmlwidget parameter in plot
plot(subRules_robbery, method = "graph", engine = "htmlwidget")
## Individual Rule Representation Dataset Limpio
# Filter top 20 rules with highest lift
subRules2<-head(subRules_robbery, n=25, by="confidence")
plot(top10subRules, method="paracoord")

#Plot SubRules
plot(theft.association.rules,method="two-key plot")

subRules_theft<-theft.association.rules[quality(theft.association.rules)$confidence>0.45]
## Seleccionamos un numero limitado de reglas en el dataset limpio
top10subRules <- head(theft.association.rules, n = 10, by = "confidence")
inspect(top10subRules)
# Now, plot an interactive graph:
#Note: You can make all your plots interactive using engine=htmlwidget parameter in plot
plot(subRules_theft, method = "graph", engine = "htmlwidget")
## Individual Rule Representation
plot(top10subRules, method="paracoord")

#Plot SubRules
plot(vc.association.rules,method="two-key plot")

subRules_vc<-vc.association.rules[quality(vc.association.rules)$confidence>0.15]
## Seleccionamos un numero limitado de reglas en el dataset limpio
top10subRules <- head(vc.association.rules, n = 10, by = "confidence")
inspect(top10subRules)
# Now, plot an interactive graph:
#Note: You can make all your plots interactive using engine=htmlwidget parameter in plot
plot(subRules_vc, method = "graph", engine = "htmlwidget")
## Individual Rule Representation
plot(top10subRules, method="paracoord")

#Plot SubRules
plot(wv.association.rules,method="two-key plot")

subRules_wv<-wv.association.rules[quality(wv.association.rules)$confidence>0.1]
## Seleccionamos un numero limitado de reglas en el dataset limpio
top10subRules <- head(wv.association.rules, n = 10, by = "confidence")
inspect(top10subRules)
# Now, plot an interactive graph:
#Note: You can make all your plots interactive using engine=htmlwidget parameter in plot
plot(subRules_wv, method = "graph", engine = "htmlwidget")
## Individual Rule Representation
plot(top10subRules, method="paracoord")

#Plot SubRules
plot(ocho.association.rules,method="two-key plot")

subRules_8<-ocho.association.rules[quality(ocho.association.rules)$confidence>0.01]
## Seleccionamos un numero limitado de reglas en el dataset limpio
top10subRules <- head(ocho.association.rules, n = 20, by = "confidence")
inspect(top10subRules)
# Now, plot an interactive graph:
#Note: You can make all your plots interactive using engine=htmlwidget parameter in plot
plot(subRules_8, method = "graph", engine = "htmlwidget")
## Individual Rule Representation
plot(top10subRules, method="paracoord")

Mapas de Densidad
## INITIALIZE
library("leaflet")
library("data.table")
library("sp")
library("rgdal")
# library("maptools")
library("KernSmooth")
library(viridis)
Loading required package: viridisLite
library(RColorBrewer)
assault <- na.omit(assault)
setDT(assault)
criminal_damage <- na.omit(criminal_damage)
setDT(criminal_damage)
deceptive_practice <- na.omit(deceptive_practice)
setDT(deceptive_practice)
narcotics <- na.omit(narcotics)
setDT(narcotics)
robbery <- na.omit(robbery)
setDT(robbery)
theft <- na.omit(theft)
setDT(theft)
violent_crime <- na.omit(violent_crime)
setDT(violent_crime)
weapons_violation <- na.omit(weapons_violation)
setDT(weapons_violation)
## MAKE CONTOUR LINES
## Assault
kde_assault <- bkde2D(assault[ , list(longitude, latitude)],
bandwidth=c(.0001, .0001), gridsize = c(75,75))
Binning grid too coarse for current (small) bandwidth: consider increasing 'gridsize'
CL_assault <- contourLines(kde_assault$x1 , kde_assault$x2 , kde_assault$fhat)
## EXTRACT CONTOUR LINE LEVELS
LEVS_assault<- as.factor(sapply(CL_assault, `[[`, "level"))
NLEV_assault <- length(levels(LEVS_assault))
## CONVERT CONTOUR LINES TO POLYGONS
pgons_assault <- lapply(1:length(CL_assault), function(i)
Polygons(list(Polygon(cbind(CL_assault[[i]]$x, CL_assault[[i]]$y))), ID=i))
spgons_assault = SpatialPolygons(pgons_assault)
## Criminal Damage
kde_cd <- bkde2D(criminal_damage[ , list(longitude, latitude)],
bandwidth=c(.0001, .0001), gridsize = c(75,75))
Binning grid too coarse for current (small) bandwidth: consider increasing 'gridsize'
CL_cd <- contourLines(kde_cd$x1 , kde_cd$x2 , kde_cd$fhat)
## EXTRACT CONTOUR LINE LEVELS
LEVS_cd<- as.factor(sapply(CL_cd, `[[`, "level"))
NLEV_cd <- length(levels(LEVS_cd))
## CONVERT CONTOUR LINES TO POLYGONS
pgons_cd <- lapply(1:length(CL_cd), function(i)
Polygons(list(Polygon(cbind(CL_cd[[i]]$x, CL_cd[[i]]$y))), ID=i))
less than 4 coordinates in polygonless than 4 coordinates in polygon
spgons_cd = SpatialPolygons(pgons_cd)
## Deceptive Practice
kde_dp <- bkde2D(deceptive_practice[ , list(longitude, latitude)],
bandwidth=c(.0001, .0001), gridsize = c(75,75))
Binning grid too coarse for current (small) bandwidth: consider increasing 'gridsize'
CL_dp <- contourLines(kde_dp$x1 , kde_dp$x2 , kde_dp$fhat)
## EXTRACT CONTOUR LINE LEVELS
LEVS_dp<- as.factor(sapply(CL_dp, `[[`, "level"))
NLEV_dp <- length(levels(LEVS_dp))
## CONVERT CONTOUR LINES TO POLYGONS
pgons_dp <- lapply(1:length(CL_dp), function(i)
Polygons(list(Polygon(cbind(CL_dp[[i]]$x, CL_dp[[i]]$y))), ID=i))
spgons_dp = SpatialPolygons(pgons_dp)
## Narcotics
kde_narcotics <- bkde2D(narcotics[ , list(longitude, latitude)],
bandwidth=c(.0001, .0001), gridsize = c(75,75))
Binning grid too coarse for current (small) bandwidth: consider increasing 'gridsize'
CL_narcotics <- contourLines(kde_narcotics$x1 , kde_narcotics$x2 , kde_narcotics$fhat)
## EXTRACT CONTOUR LINE LEVELS
LEVS_narcotics <- as.factor(sapply(CL_narcotics, `[[`, "level"))
NLEV_narcotics <- length(levels(LEVS_narcotics))
## CONVERT CONTOUR LINES TO POLYGONS
pgons_narcotics <- lapply(1:length(CL_narcotics), function(i)
Polygons(list(Polygon(cbind(CL_narcotics[[i]]$x, CL_narcotics[[i]]$y))), ID=i))
spgons_narcotics = SpatialPolygons(pgons_narcotics)
## Robbery
kde_robbery <- bkde2D(robbery[ , list(longitude, latitude)],
bandwidth=c(.0001, .0001), gridsize = c(75,75))
Binning grid too coarse for current (small) bandwidth: consider increasing 'gridsize'
CL_robbery <- contourLines(kde_robbery$x1 , kde_robbery$x2 , kde_robbery$fhat)
## EXTRACT CONTOUR LINE LEVELS
LEVS_robbery <- as.factor(sapply(CL_robbery, `[[`, "level"))
NLEV_robbery <- length(levels(LEVS_robbery))
## CONVERT CONTOUR LINES TO POLYGONS
pgons_robbery <- lapply(1:length(CL_robbery), function(i)
Polygons(list(Polygon(cbind(CL_robbery[[i]]$x, CL_robbery[[i]]$y))), ID=i))
spgons_robbery = SpatialPolygons(pgons_robbery)
## Thefts
kde_theft <- bkde2D(theft[ , list(longitude, latitude)],
bandwidth=c(.0001, .0001), gridsize = c(75,75))
Binning grid too coarse for current (small) bandwidth: consider increasing 'gridsize'
CL_theft <- contourLines(kde_theft$x1 , kde_theft$x2 , kde_theft$fhat)
## EXTRACT CONTOUR LINE LEVELS
LEVS_theft <- as.factor(sapply(CL_theft, `[[`, "level"))
NLEV_theft <- length(levels(LEVS_theft))
## CONVERT CONTOUR LINES TO POLYGONS
pgons_theft <- lapply(1:length(CL_theft), function(i)
Polygons(list(Polygon(cbind(CL_theft[[i]]$x, CL_theft[[i]]$y))), ID=i))
spgons_theft = SpatialPolygons(pgons_theft)
## Violent Crimws
kde_vc <- bkde2D(violent_crime[ , list(longitude, latitude)],
bandwidth=c(.0001, .0001), gridsize = c(75,75))
Binning grid too coarse for current (small) bandwidth: consider increasing 'gridsize'
CL_vc <- contourLines(kde_vc$x1 , kde_vc$x2 , kde_vc$fhat)
## EXTRACT CONTOUR LINE LEVELS
LEVS_vc <- as.factor(sapply(CL_vc, `[[`, "level"))
NLEV_vc <- length(levels(LEVS_vc))
## CONVERT CONTOUR LINES TO POLYGONS
pgons_vc <- lapply(1:length(CL_vc), function(i)
Polygons(list(Polygon(cbind(CL_vc[[i]]$x, CL_vc[[i]]$y))), ID=i))
spgons_vc = SpatialPolygons(pgons_vc)
## Weapons Violation
kde_wv <- bkde2D(weapons_violation[ , list(longitude, latitude)],
bandwidth=c(.0001, .0001), gridsize = c(75,75))
Binning grid too coarse for current (small) bandwidth: consider increasing 'gridsize'
CL_wv <- contourLines(kde_wv$x1 , kde_wv$x2 , kde_wv$fhat)
## EXTRACT CONTOUR LINE LEVELS
LEVS_wv <- as.factor(sapply(CL_wv, `[[`, "level"))
NLEV_wv <- length(levels(LEVS_wv))
## CONVERT CONTOUR LINES TO POLYGONS
pgons_wv <- lapply(1:length(CL_wv), function(i)
Polygons(list(Polygon(cbind(CL_wv[[i]]$x, CL_wv[[i]]$y))), ID=i))
less than 4 coordinates in polygon
spgons_wv = SpatialPolygons(pgons_wv)
leaflet() %>% addTiles() %>%
addPolygons(data = spgons_narcotics, color = brewer.pal(NLEV_narcotics, name = "YlOrRd")[LEVS_narcotics], group = "Narcotics") %>%
addPolygons(data = spgons_assault, color = brewer.pal(NLEV_assault, name = "Reds")[LEVS_assault], group = "Assault") %>%
addPolygons(data = spgons_cd, color = brewer.pal(NLEV_cd, name="YlGnBu")[LEVS_cd], group = "Criminal Damage") %>%
addPolygons(data = spgons_dp, color = brewer.pal(NLEV_dp, name = "YlGn")[LEVS_dp], group = "Deceptive Practice") %>%
addPolygons(data = spgons_robbery, color = brewer.pal(NLEV_robbery, name = "Purples")[LEVS_robbery], group = "Robbery") %>%
addPolygons(data = spgons_theft, color = brewer.pal(NLEV_theft, name = "Oranges")[LEVS_theft], group = "Thefts") %>%
addPolygons(data = spgons_vc, color = brewer.pal(NLEV_vc, name = "Greys")[LEVS_vc], group = "Violent Crimes") %>%
addPolygons(data = spgons_wv, color = brewer.pal(NLEV_wv, name = "Blues")[LEVS_wv], group = "Weapons Violation") %>%
addLabelOnlyMarkers(districts$longitude, districts$latitude, label = districts$district,
labelOptions = labelOptions(noHide = T, direction = 'top', textOnly = T), group = "Districts") %>%
addLayersControl(overlayGroups = c("Assault", "Criminal Damage","Deceptive Practice", "Narcotics","Robbery","Thefts","Violent Crimes","Weapons Violation", "Districts"),options = layersControlOptions(collapsed = FALSE))
n too large, allowed maximum for palette YlOrRd is 9
Returning the palette you asked for with that many colors
n too large, allowed maximum for palette Reds is 9
Returning the palette you asked for with that many colors
n too large, allowed maximum for palette YlGnBu is 9
Returning the palette you asked for with that many colors
n too large, allowed maximum for palette YlGn is 9
Returning the palette you asked for with that many colors
n too large, allowed maximum for palette Greys is 9
Returning the palette you asked for with that many colors
#addCircles(lng = narcotics$longitude, lat = narcotics$latitude,radius = .1, opacity = .4, col = "blue", group = "Points") %>%
#leaflet() %>% addTiles() %>%
# addCircles(lng = weapons_violation$longitude, lat = weapons_violation$latitude,radius = .05, opacity = 0.1, col = brewer.pal(10,name = "Reds"), group = "Narcotics") %>%
# addLabelOnlyMarkers(districts$longitude, districts$latitude, label = districts$district,
# labelOptions = labelOptions(noHide = T, direction = 'top', textOnly = T, textsize = "15px"), group = #"Districts") %>%
# addLayersControl(overlayGroups = c("Assault", "Criminal Damage","Deceptive Practice", "Narcotics","Robbery","Thefts","Violent Crimes","Weapons Violation", "Districts"),options = layersControlOptions(collapsed = FALSE))
Clustering
chicago_crime_clustering <- subset(chicago_crime_subset, select=-c(location_description,case_number,block,ward,description,day,month,latitude,longitude))
unique(chicago_crime_clustering$primary_type)
[1] ASSAULT NARCOTICS DECEPTIVE PRACTICE ROBBERY WEAPONS VIOLATION THEFT VIOLENT CRIME
[8] CRIMINAL DAMAGE
Levels: ASSAULT CRIMINAL DAMAGE DECEPTIVE PRACTICE NARCOTICS ROBBERY THEFT VIOLENT CRIME WEAPONS VIOLATION
library(data.table)
library(mltools)
#Crime_chicago_dummy <- one_hot(as.data.table(Crime_chicago_def_clust))
types <- unique(chicago_crime_clustering$primary_type)
chicago_crime_clustering$primary_type <- match(chicago_crime_clustering$primary_type, unique(chicago_crime_clustering$primary_type))
chicago_crime_clustering$arrest <- match(chicago_crime_clustering$arrest, unique(chicago_crime_clustering$arrest))
#chicago_crime_clustering$location_description <- match(chicago_crime_clustering$location_description, unique(chicago_crime_clustering$location_description))
chicago_crime_clustering$district <- as.numeric(chicago_crime_clustering$district)
test <- chicago_crime_clustering
#Normalization of variables
library(RSNNS)
train_set <- subset(chicago_crime_subset_tr, select=-c(location_description,case_number,block,ward,description,day,month,latitude,longitude))
train_set$primary_type <- match(train_set$primary_type, unique(train_set$primary_type))
train_set$arrest <- match(train_set$arrest, unique(train_set$arrest))
#train_set$location_description <- match(train_set$location_description, unique(train_set$location_description))
train_set$district <- as.numeric(train_set$district)
#index <- sample(nrow(chicago_crime_clustering_cut), round(0.75*nrow(chicago_crime_clustering_cut)))
#train <- Crime_chicago_def_clust_cut[index,]
#test <- Crime_chicago_def_clust_cut[-index,]
train_label <- train_set[,1]
test_label <- test[,1]
#Optimum number of clusters. Elbow method
# Alternative using fviz function for Elbow method
library(factoextra)
library(NbClust)
set.seed(123)
train_small <- train_set[1:1000,]
test_small <- test[1:100,]
## Dendograms
library(tidyverse) #data manipulation and visualization
library(class) # to call class package for kNN
library(caret)
library(cluster)
# Divisive Hierarchical Clustering - diana
# compute divisive hierarchical clustering
div <- diana(train_small)
plot(div, main = "Divisive")


distance <- dist(train_small,method = "euclidean")
agg <- hclust(distance, method = "complete")
plot(agg,
main = "Agglomerative, complete linkages")

library(fpc)
cstats.table <- function(dist, tree, k) {
clust.assess <- c("cluster.number","n","within.cluster.ss","average.within","average.between",
"wb.ratio","dunn2","avg.silwidth")
clust.size <- c("cluster.size")
stats.names <- c()
row.clust <- c()
output.stats <- matrix(ncol = k, nrow = length(clust.assess))
cluster.sizes <- matrix(ncol = k, nrow = k)
for(i in c(1:k)){
row.clust[i] <- paste("Cluster-", i, " size")
}
for(i in c(2:k)){
stats.names[i] <- paste("Test", i-1)
for(j in seq_along(clust.assess)){
output.stats[j, i] <- unlist(cluster.stats(d = dist, clustering = cutree(tree, k = i))[clust.assess])[j]
}
for(d in 1:k) {
cluster.sizes[d, i] <- unlist(cluster.stats(d = dist, clustering = cutree(tree, k = i))[clust.size])[d]
dim(cluster.sizes[d, i]) <- c(length(cluster.sizes[i]), 1)
cluster.sizes[d, i]
}
}
output.stats.df <- data.frame(output.stats)
cluster.sizes <- data.frame(cluster.sizes)
cluster.sizes[is.na(cluster.sizes)] <- 0
rows.all <- c(clust.assess, row.clust)
# rownames(output.stats.df) <- clust.assess
output <- rbind(output.stats.df, cluster.sizes)[ ,-1]
colnames(output) <- stats.names[2:k]
rownames(output) <- rows.all
is.num <- sapply(output, is.numeric)
output[is.num] <- lapply(output[is.num], round, 2)
output
}
# I am capping the maximum amout of clusters by 7
# I want to choose a reasonable number, based on which I will be able to see basic differences between customer groups as a result
stats.df.divisive <- cstats.table(distance, div, 7)
stats.df.divisive
stats.df.aggl <-cstats.table(distance, agg, 7) #complete linkages looks like the most balanced approach
stats.df.aggl
#confusionMatrix(train_small, )
library(data.table)
library(mltools)
#Crime_chicago_dummy <- one_hot(as.data.table(Crime_chicago_def_clust))
#narcotics <- subset(narcotics, select=-c(case_number,block,ward,description,day,month,latitude,longitude))
#narcotics_tr <- subset(narcotics_tr, select=-c(case_number,block,ward,description,day,month,latitude,longitude))
narcotics_clustering <- subset(narcotics, select=-c(location_description))
narcotics_clustering_tr <- subset(narcotics_tr, select=-c(location_description))
types <- unique(chicago_crime_clustering$primary_type)
narcotics_clustering$primary_type <- match(chicago_crime_clustering$primary_type, unique(chicago_crime_clustering$primary_type))
narcotics_clustering$arrest <- match(chicago_crime_clustering$arrest, unique(chicago_crime_clustering$arrest))
#narcotics_clustering$location_description <- match(chicago_crime_clustering$location_description, unique(narcotics_clustering$location_description))
narcotics_clustering$district <- as.numeric(narcotics_clustering$district)
test <- narcotics_clustering
#Normalization of variables
library(RSNNS)
train_set <- narcotics_clustering_tr
train_set$primary_type <- match(train_set$primary_type, unique(train_set$primary_type))
train_set$arrest <- match(train_set$arrest, unique(train_set$arrest))
#train_set$location_description <- match(train_set$location_description, unique(train_set$location_description))
train_set$district <- as.numeric(train_set$district)
#index <- sample(nrow(chicago_crime_clustering_cut), round(0.75*nrow(chicago_crime_clustering_cut)))
#train <- Crime_chicago_def_clust_cut[index,]
#test <- Crime_chicago_def_clust_cut[-index,]
train_label <- train_set[,1]
test_label <- test[,1]
#Optimum number of clusters. Elbow method
# Alternative using fviz function for Elbow method
library(factoextra)
library(NbClust)
set.seed(123)
train_small <- train_set[1:1000,]
test_small <- test[1:100,]
## Dendograms
library(tidyverse) #data manipulation and visualization
library(class) # to call class package for kNN
library(caret)
library(cluster)
# Divisive Hierarchical Clustering - diana
# compute divisive hierarchical clustering
div <- diana(train_small)
plot(div, main = "Divisive")


distance <- dist(train_small,method = "euclidean")
agg <- hclust(distance, method = "complete")
plot(agg,
main = "Agglomerative, complete linkages")

library(fpc)
cstats.table <- function(dist, tree, k) {
clust.assess <- c("cluster.number","n","within.cluster.ss","average.within","average.between",
"wb.ratio","dunn2","avg.silwidth")
clust.size <- c("cluster.size")
stats.names <- c()
row.clust <- c()
output.stats <- matrix(ncol = k, nrow = length(clust.assess))
cluster.sizes <- matrix(ncol = k, nrow = k)
for(i in c(1:k)){
row.clust[i] <- paste("Cluster-", i, " size")
}
for(i in c(2:k)){
stats.names[i] <- paste("Test", i-1)
for(j in seq_along(clust.assess)){
output.stats[j, i] <- unlist(cluster.stats(d = dist, clustering = cutree(tree, k = i))[clust.assess])[j]
}
for(d in 1:k) {
cluster.sizes[d, i] <- unlist(cluster.stats(d = dist, clustering = cutree(tree, k = i))[clust.size])[d]
dim(cluster.sizes[d, i]) <- c(length(cluster.sizes[i]), 1)
cluster.sizes[d, i]
}
}
output.stats.df <- data.frame(output.stats)
cluster.sizes <- data.frame(cluster.sizes)
cluster.sizes[is.na(cluster.sizes)] <- 0
rows.all <- c(clust.assess, row.clust)
# rownames(output.stats.df) <- clust.assess
output <- rbind(output.stats.df, cluster.sizes)[ ,-1]
colnames(output) <- stats.names[2:k]
rownames(output) <- rows.all
is.num <- sapply(output, is.numeric)
output[is.num] <- lapply(output[is.num], round, 2)
output
}
# I am capping the maximum amout of clusters by 7
# I want to choose a reasonable number, based on which I will be able to see basic differences between customer groups as a result
stats.df.divisive <- cstats.table(distance, div, 7)
stats.df.divisive
stats.df.aggl <-cstats.table(distance, agg, 7) #complete linkages looks like the most balanced approach
stats.df.aggl
#confusionMatrix(train_small, )
library("ggplot2")
library("reshape2")
Attaching package: ‘reshape2’
The following object is masked from ‘package:tidyr’:
smiths
The following objects are masked from ‘package:data.table’:
dcast, melt
library("purrr")
library("dplyr")
# let's start with a dendrogram
library("dendextend")
---------------------
Welcome to dendextend version 1.13.4
Type citation('dendextend') for how to cite the package.
Type browseVignettes(package = 'dendextend') for the package vignette.
The github page is: https://github.com/talgalili/dendextend/
Suggestions and bug-reports can be submitted at: https://github.com/talgalili/dendextend/issues
Or contact: <tal.galili@gmail.com>
To suppress this message use: suppressPackageStartupMessages(library(dendextend))
---------------------
Attaching package: ‘dendextend’
The following object is masked from ‘package:data.table’:
set
The following object is masked from ‘package:stats’:
cutree
dendro <- as.dendrogram(agg)
dendro.col <- dendro %>%
set("branches_k_color", k = 8, value = c("darkslategray", "darkslategray4", "darkslategray3", "gold3", "darkcyan", "cyan3", "gold3")) %>%
set("branches_lwd", 0.6) %>%
set("labels_colors",
value = c("darkslategray")) %>%
set("labels_cex", 0.5)
Length of color vector was shorter than the number of clusters - color vector was recycled
ggd1 <- as.ggdend(dendro.col)
ggplot(ggd1, theme = theme_minimal()) +
labs(x = "Num. observations", y = "Height", title = "Dendrogram, k = 8")

NA
NA
NA
Arboles de Decision
## c50
library(dplyr)
library(MASS) # for obtaining data
library(tidyverse) # for data processing
library(rpart) # for CART decision tree
library(rpart.plot) # for plotting CART
library(caret) # for confusion matrix and more
library(rsample) # for data splitting
library(data.table)
library(C50)
#levels(chicago_crime$location_description)[1] = "None"
## Creating a training and test datasets
set.seed(1234)
chicago_crime_trees <- subset(chicago_crime_subset, select=-c(location_description,case_number,block,ward,description,day,month,latitude,longitude))
chicago_crime_trees_tr <- subset(chicago_crime_subset_tr, select=-c(location_description,case_number,block,ward,description,day,month,latitude,longitude))
library(dplyr)
chicago_crime_trees %>% mutate_if(is.factor, as.character) -> chicago_crime_trees
chicago_crime_trees_tr %>% mutate_if(is.factor, as.character) -> chicago_crime_trees_tr
chicago_crime_trees$primary_type[chicago_crime_trees$primary_type == "ROBBERY"] <- "ROB"
chicago_crime_trees$primary_type[chicago_crime_trees$primary_type == "NARCOTICS"] <- "NAR"
chicago_crime_trees$primary_type[chicago_crime_trees$primary_type == "ASSAULT"] <- "ASS"
chicago_crime_trees$primary_type[chicago_crime_trees$primary_type == "WEAPONS VIOLATION"] <- "WV"
chicago_crime_trees$primary_type[chicago_crime_trees$primary_type == "CRIMINAL DAMAGE"] <- "CD"
chicago_crime_trees$primary_type[chicago_crime_trees$primary_type == "VIOLENT CRIME"] <- "VC"
chicago_crime_trees$primary_type[chicago_crime_trees$primary_type == "DECEPTIVE PRACTICE"] <- "DP"
chicago_crime_trees$primary_type[chicago_crime_trees$primary_type == "THEFT"] <- "TH"
chicago_crime_trees_tr$primary_type[chicago_crime_trees_tr$primary_type == "ROBBERY"] <- "ROB"
chicago_crime_trees_tr$primary_type[chicago_crime_trees_tr$primary_type == "NARCOTICS"] <- "NAR"
chicago_crime_trees_tr$primary_type[chicago_crime_trees_tr$primary_type == "ASSAULT"] <- "ASS"
chicago_crime_trees_tr$primary_type[chicago_crime_trees_tr$primary_type == "WEAPONS VIOLATION"] <- "WV"
chicago_crime_trees_tr$primary_type[chicago_crime_trees_tr$primary_type == "CRIMINAL DAMAGE"] <- "CD"
chicago_crime_trees_tr$primary_type[chicago_crime_trees_tr$primary_type == "VIOLENT CRIME"] <- "VC"
chicago_crime_trees_tr$primary_type[chicago_crime_trees_tr$primary_type == "DECEPTIVE PRACTICE"] <- "DP"
chicago_crime_trees_tr$primary_type[chicago_crime_trees_tr$primary_type == "THEFT"] <- "TH"
#train_c50<- chicago_crime_trees_tr
#test_c50<- chicago_crime_trees
crime_split_c50<- initial_split(subset(chicago_crime_subset_tr, select=-c(location_description,case_number,block,ward,description,day,month,latitude,longitude)), prop=0.8)
train_c50<- training(crime_split_c50)
test_c50<- testing(crime_split_c50)
#train_c50$location_description <- as.factor(train_c50$location_description)
#test_c50$location_description <- as.factor(test_c50$location_description)
#train_c50$arrest <- as.numeric(train_c50$arrest, unique(train_c50$arrest))
#test_c50$arrest <- as.numeric(test_c50$arrest, unique(test_c50$arrest))
#train_c50$primary_type <- as.numeric(train_c50$primary_type, unique(train_c50$primary_type))
#test_c50$primary_type <- as.numeric(test_c50$primary_type, unique(test_c50$primary_type))
#train_c50$location_description <- as.numeric(train_c50$location_description, unique(train_c50$location_description))
#test_c50$location_description <- as.numeric(test_c50$location_description, unique(test_c50$location_description))
#train_c50$district <- as.numeric(train_c50$district, unique(train_c50$district))
#test_c50$district <- as.numeric(test_c50$district, unique(test_c50$district))
train_c50$arrest <- as.factor(train_c50$arrest)
test_c50$arrest <- as.factor(test_c50$arrest)
train_c50$district <- as.factor(train_c50$district)
test_c50$district <- as.factor(test_c50$district)
train_c50$primary_type <- as.factor(train_c50$primary_type)
test_c50$primary_type <- as.factor(test_c50$primary_type)
#Creating the decision tree algorithm C4.5
tree_result <- C5.0(primary_type ~ ., data=train_c50, control = C5.0Control(noGlobalPruning = FALSE, CF= 0.2)) #Higher CF less prunning
summary(tree_result)
Call:
C5.0.formula(formula = primary_type ~ ., data = train_c50, control = C5.0Control(noGlobalPruning = FALSE, CF = 0.2))
C5.0 [Release 2.07 GPL Edition] Fri May 8 13:49:43 2020
-------------------------------
Class specified by attribute `outcome'
Read 488358 cases (3 attributes) from undefined.data
Decision tree:
arrest = False: THEFT (396262/242319)
arrest = True:
:...district in {1,2,12,14,16,17,18,19,20,24,31}: THEFT (29329/19863)
district in {3,4,5,6,7,8,9,10,11,15,22,25}: NARCOTICS (62767/36815)
Evaluation on training data (488358 cases):
Decision Tree
----------------
Size Errors
3 298997(61.2%) <<
(a) (b) (c) (d) (e) (f) (g) (h) <-classified as
----- ----- ----- ----- ----- ----- ----- -----
4197 30630 (a): class ASSAULT
1976 60313 (b): class CRIMINAL DAMAGE
970 41627 (c): class DECEPTIVE PRACTICE
25952 4001 (d): class NARCOTICS
7181 65181 (e): class ROBBERY
7604 163409 (f): class THEFT
7881 56651 (g): class VIOLENT CRIME
7006 3779 (h): class WEAPONS VIOLATION
Attribute usage:
100.00% arrest
18.86% district
Time: 0.2 secs
#Plotting the tree
plot(tree_result,subtree=NULL)

## PREDICTION
#Prediction of new cases from the test dataset
predictions <- predict(tree_result, newdata = test_c50, type ="class")
#table(prediction=predictions, real= crime_test_c50$primary_type)
#crime_test_c50$primary_type <- factor(crime_test_c50$primary_type)
error_classification <- mean(predictions != test_c50$primary_type)
paste("The classification error in test set is:", 100*error_classification, "%",
sum(predictions==test_c50$primary_type),
"correct classified cases from", length(predictions))
[1] "The classification error in test set is: 61.0087722890678 % 47604 correct classified cases from 122089"
pred_train <- predict(tree_result, newdata = train_c50)
#confusionMatrix(pred_train, crime_train$district)
#pred_train<-round(pred_train)
#table(prediction=pred_train, real= crime_train_c50$arrest)
error_classification <- mean(pred_train != train_c50$primary_type)
paste("The classification error in train set is:", 100*error_classification, "%",
sum(pred_train==train_c50$primary_type),
"correct classified cases from", length(pred_train))
[1] "The classification error in train set is: 61.2249620155705 % 189361 correct classified cases from 488358"
#Creating the decision tree algorithm C4.5
tree_result <- C5.0(district ~ ., data=train_c50, control = C5.0Control(noGlobalPruning = FALSE, CF= 0.1)) #Higher CF less prunning
summary(tree_result)
Call:
C5.0.formula(formula = district ~ ., data = train_c50, control = C5.0Control(noGlobalPruning = FALSE, CF = 0.1))
C5.0 [Release 2.07 GPL Edition] Fri May 8 13:47:32 2020
-------------------------------
Class specified by attribute `outcome'
Read 488358 cases (4 attributes) from undefined.data
Decision tree:
primary_type in {NARCOTICS,WEAPONS VIOLATION}:
:...primary_type = WEAPONS VIOLATION:
: :...arrest = False:
: : :...location_description <= 18:
: : : :...location_description <= 14: 7 (9/6)
: : : : location_description > 14: 25 (400/355)
: : : location_description > 18:
: : : :...location_description <= 19: 11 (210/167)
: : : location_description > 19:
: : : :...location_description > 128: 11 (1516/1354)
: : : location_description <= 128:
: : : :...location_description > 110: 7 (534/464)
: : : location_description <= 110:
: : : :...location_description <= 64: 5 (50/39)
: : : location_description > 64: 4 (150/131)
: : arrest = True:
: : :...location_description > 113:
: : :...location_description <= 135:
: : : :...location_description <= 121: 7 (1064/902)
: : : : location_description > 121: 10 (1567/1339)
: : : location_description > 135:
: : : :...location_description <= 141: 7 (3228/2755)
: : : location_description > 141:
: : : :...location_description <= 144: 10 (72/51)
: : : location_description > 144: 11 (404/314)
: : location_description <= 113:
: : :...location_description <= 34:
: : :...location_description <= 15:
: : : :...location_description <= 4: 7 (25/16)
: : : : location_description > 4: 16 (13)
: : : location_description > 15:
: : : :...location_description <= 17: 7 (466/413)
: : : location_description > 17:
: : : :...location_description <= 19: 11 (343/293)
: : : location_description > 19:
: : : :...location_description <= 30: 15 (23/18)
: : : location_description > 30: 16 (7/4)
: : location_description > 34:
: : :...location_description <= 44: 5 (76/53)
: : location_description > 44:
: : :...location_description > 105:
: : :...location_description <= 107: 4 (90/79)
: : : location_description > 107: 6 (206/174)
: : location_description <= 105:
: : :...location_description <= 73:
: : :...location_description <= 55: 3 (41/35)
: : : location_description > 55: 1 (42/31)
: : location_description > 73:
: : :...location_description <= 77: 6 (134/104)
: : location_description > 77:
: : :...location_description <= 101: 5 (45/39)
: : location_description > 101:
: : :...location_description <= 103: 11 (63/49)
: : location_description > 103: 1 (7/4)
: primary_type = NARCOTICS:
: :...location_description > 110:
: :...location_description > 133: 11 (10740/8406)
: : location_description <= 133:
: : :...location_description > 131: 11 (8624/4943)
: : location_description <= 131:
: : :...location_description <= 113: 11 (827/288)
: : location_description > 113:
: : :...location_description <= 121:
: : :...location_description <= 116: 7 (1519/1223)
: : : location_description > 116: 11 (996/597)
: : location_description > 121:
: : :...location_description <= 127:
: : :...location_description <= 124: 11 (110/88)
: : : location_description > 124: 18 (52/45)
: : location_description > 127:
: : :...location_description > 129: 10 (82/69)
: : location_description <= 129:
: : :...location_description <= 128: 8 (17/14)
: : location_description > 128: 25 (369/327)
: location_description <= 110:
: :...location_description <= 19:
: :...location_description > 16: 11 (3029/2243)
: : location_description <= 16:
: : :...location_description <= 2: 11 (230/129)
: : location_description > 2: 16 (128/33)
: location_description > 19:
: :...location_description > 107: 11 (821/674)
: location_description <= 107:
: :...location_description > 77:
: :...location_description <= 79: 16 (217/44)
: : location_description > 79:
: : :...location_description > 101:
: : :...location_description <= 103: 11 (347/240)
: : : location_description > 103:
: : : :...location_description <= 105: 1 (70/4)
: : : location_description > 105: 10 (298/226)
: : location_description <= 101:
: : :...location_description <= 87: 7 (201/165)
: : location_description > 87:
: : :...location_description <= 90: 18 (31/16)
: : location_description > 90:
: : :...location_description > 98: 15 (39/31)
: : location_description <= 98:
: : :...location_description <= 92: 10 (41/28)
: : location_description > 92: 12 (59/49)
: location_description <= 77:
: :...location_description > 73: 11 (428/308)
: location_description <= 73:
: :...location_description > 62: 25 (119/106)
: location_description <= 62:
: :...location_description > 54:
: :...location_description > 59: 1 (54/31)
: : location_description <= 59:
: : :...location_description <= 57: 1 (66/49)
: : location_description > 57: 6 (83/50)
: location_description <= 54:
: :...location_description > 50: 11 (128/95)
: location_description <= 50:
: :...location_description > 44:
: :...location_description <= 48: 18 (20/9)
: : location_description > 48: 1 (13/10)
: location_description <= 44:
: :...location_description <= 27: [S1]
: location_description > 27: [S2]
primary_type in {ASSAULT,CRIMINAL DAMAGE,ROBBERY,VIOLENT CRIME}:
:...location_description <= 19:
: :...location_description <= 16:
: : :...location_description <= 2: 7 (379/308)
: : : location_description > 2: 16 (777/111)
: : location_description > 16:
: : :...location_description > 18: 3 (28087/24753)
: : location_description <= 18:
: : :...location_description > 17: 18 (39/34)
: : location_description <= 17:
: : :...primary_type in {CRIMINAL DAMAGE,
: : : VIOLENT CRIME}: 11 (2839/2595)
: : primary_type = ASSAULT:
: : :...arrest = False: 25 (785/709)
: : : arrest = True: 11 (179/162)
: : primary_type = ROBBERY:
: : :...arrest = False: 11 (1916/1722)
: : arrest = True: 19 (159/142)
: location_description > 19:
: :...location_description <= 109:
: :...location_description <= 40:
: : :...location_description > 34:
: : : :...location_description > 38: 5 (868/648)
: : : : location_description <= 38:
: : : : :...location_description <= 36: 5 (742/599)
: : : : location_description > 36:
: : : : :...primary_type = CRIMINAL DAMAGE: 19 (7/5)
: : : : primary_type in {ROBBERY,
: : : : : VIOLENT CRIME}: 1 (193/124)
: : : : primary_type = ASSAULT:
: : : : :...arrest = False: 2 (82/53)
: : : : arrest = True: 1 (22/15)
: : : location_description <= 34:
: : : :...location_description <= 25:
: : : :...primary_type in {ASSAULT,CRIMINAL DAMAGE,ROBBERY}:
: : : : :...location_description <= 20: 9 (49/42)
: : : : : location_description > 20: 1 (602/506)
: : : : primary_type = VIOLENT CRIME:
: : : : :...location_description <= 21:
: : : : :...location_description <= 20: 6 (20/16)
: : : : : location_description > 20: 1 (46/35)
: : : : location_description > 21:
: : : : :...location_description <= 24: 8 (198/173)
: : : : location_description > 24: 1 (24/17)
: : : location_description > 25:
: : : :...location_description <= 26:
: : : :...primary_type in {ASSAULT,CRIMINAL DAMAGE,
: : : : : ROBBERY}: 19 (470/369)
: : : : primary_type = VIOLENT CRIME: 18 (1234/866)
: : : location_description > 26:
: : : :...location_description > 32: 17 (176/153)
: : : location_description <= 32:
: : : :...location_description <= 29: 6 (314/281)
: : : location_description > 29:
: : : :...location_description <= 30: 1 (30/12)
: : : location_description > 30: [S3]
: : location_description > 40:
: : :...location_description <= 79:
: : :...location_description > 73:
: : : :...location_description > 77: 1 (538/424)
: : : : location_description <= 77:
: : : : :...primary_type = CRIMINAL DAMAGE: 6 (557/488)
: : : : primary_type in {ASSAULT,ROBBERY,VIOLENT CRIME}:
: : : : :...primary_type = ASSAULT: 6 (798/697)
: : : : primary_type = ROBBERY: 11 (1721/1425)
: : : : primary_type = VIOLENT CRIME:
: : : : :...location_description <= 75: 10 (7/4)
: : : : location_description > 75: 11 (850/747)
: : : location_description <= 73:
: : : :...primary_type = CRIMINAL DAMAGE:
: : : :...location_description <= 54:
: : : : :...location_description <= 44:
: : : : : :...arrest = False: 2 (286/255)
: : : : : : arrest = True: 7 (9/6)
: : : : : location_description > 44:
: : : : : :...location_description <= 50:
: : : : : :...location_description <= 46: 4 (45/39)
: : : : : : location_description > 46:
: : : : : : :...location_description <= 47: 1 (21/15)
: : : : : : location_description > 47: 12 (627/559)
: : : : : location_description > 50:
: : : : : :...location_description <= 52:
: : : : : :...location_description <= 51: 1 (225/203)
: : : : : : location_description > 51: 6 (7/4)
: : : : : location_description > 52:
: : : : : :...arrest = True: 9 (32/27)
: : : : : arrest = False: [S4]
: : : : location_description > 54:
: : : : :...location_description <= 60:
: : : : :...arrest = False: 24 (810/591)
: : : : : arrest = True: 1 (74/53)
: : : : location_description > 60:
: : : : :...arrest = True: 3 (44/38)
: : : : arrest = False:
: : : : :...location_description > 64: 8 (540/468)
: : : : location_description <= 64:
: : : : :...location_description > 62: 18 (110/89)
: : : : location_description <= 62: [S5]
: : : primary_type in {ASSAULT,ROBBERY,VIOLENT CRIME}:
: : : :...location_description <= 54:
: : : :...location_description > 50:
: : : : :...location_description > 52:
: : : : : :...location_description <= 53: 6 (1016/913)
: : : : : : location_description > 53: 11 (653/584)
: : : : : location_description <= 52: [S6]
: : : : location_description <= 50:
: : : : :...location_description > 46:
: : : : :...location_description <= 48: 1 (140/98)
: : : : : location_description > 48:
: : : : : :...location_description <= 49: 1 (1110/952)
: : : : : location_description > 49: 12 (336/275)
: : : : location_description <= 46:
: : : : :...arrest = True:
: : : : :...location_description <= 44: 18 (87/77)
: : : : : location_description > 44: 5 (39/31)
: : : : arrest = False:
: : : : :...location_description > 43: 8 (91/78)
: : : : location_description <= 43: [S7]
: : : location_description > 54:
: : : :...location_description <= 60:
: : : :...primary_type in {ASSAULT,
: : : : : VIOLENT CRIME}: 1 (1631/1245)
: : : : primary_type = ROBBERY:
: : : : :...arrest = False: 1 (700/554)
: : : : arrest = True:
: : : : :...location_description <= 57: 1 (122/98)
: : : : location_description > 57: [S8]
: : : location_description > 60:
: : : :...location_description <= 64:
: : : :...location_description <= 62: 3 (230/207)
: : : : location_description > 62: 1 (956/765)
: : : location_description > 64:
: : : :...location_description > 67:
: : : :...location_description <= 68: [S9]
: : : : location_description > 68: [S10]
: : : location_description <= 67:
: : : :...location_description > 65: [S11]
: : : location_description <= 65:
: : : :...arrest = False: 16 (196/171)
: : : arrest = True: [S12]
: : location_description > 79:
: : :...location_description <= 89:
: : :...location_description > 86:
: : : :...arrest = False: 18 (613/430)
: : : : arrest = True: 1 (348/212)
: : : location_description <= 86:
: : : :...location_description > 84:
: : : :...arrest = False: 12 (782/657)
: : : : arrest = True: 18 (384/294)
: : : location_description <= 84:
: : : :...location_description > 81: 3 (55/49)
: : : location_description <= 81:
: : : :...primary_type = ASSAULT: 18 (425/389)
: : : primary_type = CRIMINAL DAMAGE: 6 (225/205)
: : : primary_type in {ROBBERY,
: : : VIOLENT CRIME}: 19 (1236/1138)
: : location_description > 89:
: : :...location_description > 100:
: : :...arrest = True:
: : : :...location_description <= 106: 1 (1848/1539)
: : : : location_description > 106: 6 (1264/1133)
: : : arrest = False:
: : : :...primary_type = CRIMINAL DAMAGE:
: : : :...location_description > 107: 1 (3235/2863)
: : : : location_description <= 107:
: : : : :...location_description <= 105: 8 (1909/1754)
: : : : location_description > 105: 19 (257/231)
: : : primary_type in {ASSAULT,ROBBERY,VIOLENT CRIME}:
: : : :...location_description <= 104:
: : : :...location_description > 103: 1 (54/35)
: : : : location_description <= 103: [S13]
: : : location_description > 104:
: : : :...location_description > 108: 8 (2901/2669)
: : : location_description <= 108:
: : : :...location_description <= 105: 1 (63/52)
: : : location_description > 105: [S14]
: : location_description <= 100:
: : :...location_description > 98:
: : :...primary_type = CRIMINAL DAMAGE: 2 (40/34)
: : : primary_type = ROBBERY: 20 (63/56)
: : : primary_type = VIOLENT CRIME: 15 (719/607)
: : : primary_type = ASSAULT:
: : : :...arrest = False: 2 (185/161)
: : : arrest = True: 15 (16/12)
: : location_description <= 98:
: : :...location_description > 96: 18 (121/99)
: : location_description <= 96:
: : :...location_description <= 92:
: : :...location_description <= 90: 5 (54/40)
: : : location_description > 90: 12 (94/73)
: : location_description > 92:
: : :...arrest = True:
: : :...location_description <= 94: 1 (145/71)
: : : location_description > 94: 14 (24/20)
: : arrest = False:
: : :...location_description <= 93: 19 (37/27)
: : location_description > 93: [S15]
: location_description > 109:
: :...location_description <= 121:
: :...location_description > 119: 8 (13730/11829)
: : location_description <= 119:
: : :...location_description > 116:
: : :...primary_type in {ASSAULT,VIOLENT CRIME}:
: : : :...arrest = False: 11 (2154/1959)
: : : : arrest = True: 7 (449/403)
: : : primary_type in {CRIMINAL DAMAGE,ROBBERY}:
: : : :...arrest = False:
: : : :...primary_type = CRIMINAL DAMAGE: 19 (667/614)
: : : : primary_type = ROBBERY: 2 (616/568)
: : : arrest = True:
: : : :...primary_type = CRIMINAL DAMAGE: 19 (59/50)
: : : primary_type = ROBBERY: 24 (413/370)
: : location_description <= 116:
: : :...location_description <= 111:
: : :...location_description <= 110: 9 (45/37)
: : : location_description > 110:
: : : :...primary_type = ASSAULT: 19 (84/75)
: : : primary_type = VIOLENT CRIME: 11 (158/140)
: : : primary_type = ROBBERY: 3 (181/140)
: : : primary_type = CRIMINAL DAMAGE:
: : : :...arrest = False: 11 (67/57)
: : : arrest = True: 10 (61/51)
: : location_description > 111:
: : :...primary_type = ROBBERY:
: : :...arrest = False: 8 (11026/9771)
: : : arrest = True: 5 (963/871)
: : primary_type in {ASSAULT,CRIMINAL DAMAGE,
: : : VIOLENT CRIME}:
: : :...primary_type in {ASSAULT,
: : : VIOLENT CRIME}: 7 (9802/8729)
: : primary_type = CRIMINAL DAMAGE:
: : :...arrest = False: 8 (10185/9121)
: : arrest = True: 4 (418/370)
: location_description > 121:
: :...location_description <= 122:
: :...primary_type in {ASSAULT,CRIMINAL DAMAGE,
: : : ROBBERY}: 1 (4301/3863)
: : primary_type = VIOLENT CRIME: 18 (1480/1277)
: location_description > 122:
: :...location_description <= 130:
: :...location_description > 128: 8 (7069/6410)
: : location_description <= 128:
: : :...location_description <= 126: 25 (20/16)
: : location_description > 126:
: : :...primary_type in {ASSAULT,
: : : VIOLENT CRIME}: 11 (750/668)
: : primary_type = ROBBERY:
: : :...arrest = False: 12 (78/68)
: : : arrest = True: 24 (90/73)
: : primary_type = CRIMINAL DAMAGE:
: : :...arrest = True: 9 (13/10)
: : arrest = False:
: : :...location_description <= 127: 8 (87/77)
: : location_description > 127: 15 (44/38)
: location_description > 130:
: :...primary_type = CRIMINAL DAMAGE:
: :...location_description > 134: 8 (24708/22873)
: : location_description <= 134:
: : :...location_description <= 133:
: : :...arrest = False: 19 (368/337)
: : : arrest = True: 10 (168/150)
: : location_description > 133:
: : :...arrest = False: 18 (648/598)
: : arrest = True: 8 (60/50)
: primary_type in {ASSAULT,ROBBERY,VIOLENT CRIME}:
: :...location_description <= 136:
: :...location_description <= 133:
: : :...arrest = False: 11 (21858/19830)
: : : arrest = True: [S16]
: : location_description > 133:
: : :...location_description > 134: 19 (202/132)
: : location_description <= 134: [S17]
: location_description > 136:
: :...location_description > 151:
: :...location_description > 152: 7 (45/37)
: : location_description <= 152: [S18]
: location_description <= 151:
: :...primary_type = ASSAULT:
: :...location_description > 146:
: : :...arrest = False: 10 (138/125)
: : : arrest = True: 15 (27/22)
: : location_description <= 146:
: : :...location_description <= 139: [S19]
: : location_description > 139: [S20]
: primary_type in {ROBBERY,VIOLENT CRIME}:
: :...location_description <= 140:
: :...location_description <= 137: 11 (21072/19062)
: : location_description > 137: [S21]
: location_description > 140:
: :...location_description <= 144: [S22]
: location_description > 144: [S23]
primary_type in {DECEPTIVE PRACTICE,THEFT}:
:...location_description > 136:
:...location_description > 150:
: :...arrest = False: 9 (251/215)
: : arrest = True: 1 (36/28)
: location_description <= 150:
: :...primary_type = DECEPTIVE PRACTICE:
: :...arrest = False:
: : :...location_description <= 138: 1 (1926/1643)
: : : location_description > 138: 18 (668/565)
: : arrest = True:
: : :...location_description <= 138: 7 (338/306)
: : location_description > 138:
: : :...location_description > 141: 3 (30/24)
: : location_description <= 141:
: : :...location_description <= 139: 18 (6/3)
: : location_description > 139: 19 (44/35)
: primary_type = THEFT:
: :...arrest = True:
: :...location_description <= 138: 8 (1922/1757)
: : location_description > 138:
: : :...location_description > 144: 22 (118/101)
: : location_description <= 144:
: : :...location_description <= 139: 4 (66/54)
: : location_description > 139:
: : :...location_description <= 141: 19 (18/11)
: : location_description > 141: 11 (8/5)
: arrest = False:
: :...location_description <= 138: 12 (53034/48284)
: location_description > 138:
: :...location_description <= 141: 18 (552/404)
: location_description > 141:
: :...location_description <= 143: 7 (365/302)
: location_description > 143:
: :...location_description <= 146: 1 (174/142)
: location_description > 146:
: :...location_description <= 147: 14 (4302/3949)
: location_description > 147: 1 (291/254)
location_description <= 136:
:...location_description > 121:
:...location_description <= 124:
: :...arrest = False: 1 (8654/5129)
: : arrest = True: 18 (304/235)
: location_description > 124:
: :...location_description <= 131:
: :...location_description > 128: 8 (1795/1585)
: : location_description <= 128:
: : :...arrest = True: 24 (22/16)
: : arrest = False:
: : :...location_description <= 127: 1 (319/268)
: : location_description > 127: 12 (88/74)
: location_description > 131:
: :...location_description <= 133:
: :...arrest = False: 1 (5383/4398)
: : arrest = True:
: : :...primary_type = DECEPTIVE PRACTICE: 10 (168/136)
: : primary_type = THEFT: 18 (389/334)
: location_description > 133:
: :...location_description > 134: 19 (333/268)
: location_description <= 134:
: :...primary_type = DECEPTIVE PRACTICE: 18 (1467/1116)
: primary_type = THEFT: 1 (9510/7853)
location_description <= 121:
:...location_description > 109:
:...location_description > 117:
: :...location_description <= 120: 19 (5973/5206)
: : location_description > 120:
: : :...primary_type = THEFT: 8 (4387/4014)
: : primary_type = DECEPTIVE PRACTICE:
: : :...arrest = False: 16 (42/37)
: : arrest = True: 19 (10/6)
: location_description <= 117:
: :...location_description > 111:
: :...primary_type = DECEPTIVE PRACTICE: 8 (13541/12344)
: : primary_type = THEFT: 5 (10708/9898)
: location_description <= 111:
: :...location_description <= 110: 10 (65/54)
: location_description > 110:
: :...primary_type = THEFT: 11 (86/70)
: primary_type = DECEPTIVE PRACTICE:
: :...arrest = False: 9 (59/45)
: arrest = True: 5 (20/15)
location_description <= 109:
:...location_description <= 19:
:...location_description > 16:
: :...location_description <= 17: 11 (1754/1609)
: : location_description > 17: 19 (11235/10092)
: location_description <= 16:
: :...location_description > 2: 16 (1665/302)
: location_description <= 2:
: :...location_description <= 1: 19 (1757/1494)
: location_description > 1: 7 (79/61)
location_description > 19:
:...location_description <= 64:
:...location_description > 62:
: :...primary_type = DECEPTIVE PRACTICE: 18 (1288/771)
: : primary_type = THEFT: 1 (8184/5962)
: location_description <= 62:
: :...location_description <= 31:
: :...location_description > 25: 18 (2786/1577)
: : location_description <= 25:
: : :...arrest = True:
: : :...location_description > 23: 2 (70/55)
: : : location_description <= 23:
: : : :...location_description <= 20: 17 (41/26)
: : : location_description > 20: 18 (14/7)
: : arrest = False:
: : :...location_description <= 21:
: : :...location_description <= 20: 6 (77/66)
: : : location_description > 20: 1 (1059/830)
: : location_description > 21:
: : :...location_description <= 23: 19 (1204/985)
: : location_description > 23: [S24]
: location_description > 31:
: :...location_description > 55:
: :...location_description > 60: 6 (762/664)
: : location_description <= 60:
: : :...arrest = False: 1 (3966/2360)
: : arrest = True: [S25]
: location_description <= 55:
: :...location_description <= 50:
: :...location_description > 46:
: : :...location_description <= 48: 1 (213/137)
: : : location_description > 48: [S26]
: : location_description <= 46:
: : :...location_description > 34: [S27]
: : location_description <= 34: [S28]
: location_description > 50:
: :...location_description > 54: [S29]
: location_description <= 54:
: :...arrest = True: 6 (663/591)
: arrest = False: [S30]
location_description > 64:
:...location_description <= 77:
:...location_description > 74: 6 (3417/3032)
: location_description <= 74:
: :...location_description <= 65: 8 (979/817)
: location_description > 65:
: :...location_description <= 67: 1 (1995/1769)
: location_description > 67:
: :...location_description <= 69: 9 (87/72)
: location_description > 69:
: :...location_description <= 70: 1 (27/17)
: location_description > 70: 16 (54/43)
location_description > 77:
:...location_description <= 87:
:...location_description > 82: 18 (884/655)
: location_description <= 82:
: :...location_description <= 79: 1 (261/170)
: location_description > 79:
: :...primary_type = THEFT: 19 (5376/4774)
: primary_type = DECEPTIVE PRACTICE:
: :...arrest = False: 18 (438/392)
: arrest = True: 31 (24/17)
location_description > 87:
:...location_description <= 90: 18 (1670/972)
location_description > 90:
:...location_description > 107:
:...arrest = False: 1 (8715/7563)
: arrest = True: 8 (331/298)
location_description <= 107:
:...location_description > 102: 1 (1978/1288)
location_description <= 102:
:...location_description <= 93: [S31]
location_description > 93: [S32]
SubTree [S1]
location_description <= 25: 1 (12/8)
location_description > 25: 9 (12/9)
SubTree [S2]
location_description > 36: 11 (124/87)
location_description <= 36:
:...location_description <= 34: 11 (15/11)
location_description > 34: 5 (32/23)
SubTree [S3]
primary_type in {ASSAULT,ROBBERY,VIOLENT CRIME}: 18 (45/32)
primary_type = CRIMINAL DAMAGE: 19 (12/9)
SubTree [S4]
location_description <= 53: 7 (173/152)
location_description > 53: 1 (42/38)
SubTree [S5]
location_description <= 61: 6 (33/26)
location_description > 61: 8 (64/56)
SubTree [S6]
primary_type in {ASSAULT,VIOLENT CRIME}: 11 (784/701)
primary_type = ROBBERY:
:...arrest = False: 25 (492/451)
arrest = True: 7 (321/284)
SubTree [S7]
location_description <= 42: 15 (4/2)
location_description > 42:
:...primary_type = ASSAULT: 2 (84/71)
primary_type in {ROBBERY,VIOLENT CRIME}: 7 (303/272)
SubTree [S8]
location_description <= 58: 6 (297/213)
location_description > 58: 1 (87/69)
SubTree [S9]
primary_type in {ASSAULT,VIOLENT CRIME}: 9 (81/67)
primary_type = ROBBERY: 11 (54/39)
SubTree [S10]
location_description <= 70: 1 (43/30)
location_description > 70: 6 (29/24)
SubTree [S11]
primary_type in {ASSAULT,ROBBERY}: 1 (491/429)
primary_type = VIOLENT CRIME: 19 (119/100)
SubTree [S12]
primary_type in {ASSAULT,VIOLENT CRIME}: 8 (15/11)
primary_type = ROBBERY: 3 (15/12)
SubTree [S13]
primary_type in {ASSAULT,VIOLENT CRIME}: 1 (2984/2692)
primary_type = ROBBERY: 8 (1692/1525)
SubTree [S14]
location_description > 106: 11 (20/17)
location_description <= 106:
:...primary_type in {ASSAULT,VIOLENT CRIME}: 4 (1015/934)
primary_type = ROBBERY: 1 (419/376)
SubTree [S15]
primary_type = ROBBERY:
:...location_description <= 95: 1 (24/20)
: location_description > 95: 17 (44/35)
primary_type in {ASSAULT,CRIMINAL DAMAGE,VIOLENT CRIME}:
:...primary_type = VIOLENT CRIME: 1 (101/87)
primary_type = ASSAULT:
:...location_description <= 95: 12 (70/57)
: location_description > 95: 25 (67/60)
primary_type = CRIMINAL DAMAGE:
:...location_description <= 95: 16 (34/29)
location_description > 95: 19 (86/75)
SubTree [S16]
primary_type = ASSAULT: 11 (1106/1018)
primary_type = ROBBERY: 10 (754/695)
primary_type = VIOLENT CRIME: 19 (2046/1857)
SubTree [S17]
primary_type in {ASSAULT,VIOLENT CRIME}: 1 (1582/1388)
primary_type = ROBBERY:
:...arrest = False: 25 (1418/1283)
arrest = True: 1 (559/494)
SubTree [S18]
primary_type in {ASSAULT,VIOLENT CRIME}: 9 (100/79)
primary_type = ROBBERY: 12 (182/150)
SubTree [S19]
location_description > 138: 4 (91/77)
location_description <= 138:
:...arrest = False: 9 (5918/5476)
arrest = True: 4 (1141/1042)
SubTree [S20]
location_description > 143: 2 (29/23)
location_description <= 143:
:...location_description <= 141: 18 (15/11)
location_description > 141: 11 (33/27)
SubTree [S21]
location_description > 139: 18 (127/103)
location_description <= 139:
:...location_description <= 138: 4 (3/2)
location_description > 138:
:...primary_type = VIOLENT CRIME: 18 (210/172)
primary_type = ROBBERY:
:...arrest = False: 17 (105/93)
arrest = True: 4 (69/60)
SubTree [S22]
primary_type = ROBBERY:
:...arrest = False: 7 (476/398)
: arrest = True: 11 (45/38)
primary_type = VIOLENT CRIME:
:...arrest = False: 11 (99/76)
arrest = True: 7 (15/9)
SubTree [S23]
location_description <= 146: 18 (127/107)
location_description > 146:
:...location_description > 147: 18 (84/76)
location_description <= 147:
:...primary_type = ROBBERY: 8 (508/472)
primary_type = VIOLENT CRIME:
:...arrest = False: 25 (683/622)
arrest = True: 9 (95/86)
SubTree [S24]
location_description <= 24: 8 (91/77)
location_description > 24: 1 (1814/1549)
SubTree [S25]
primary_type = DECEPTIVE PRACTICE: 11 (301/183)
primary_type = THEFT: 1 (85/62)
SubTree [S26]
location_description <= 49: 1 (1772/1335)
location_description > 49: 12 (454/372)
SubTree [S27]
location_description <= 41: 5 (295/240)
location_description > 41: 2 (542/497)
SubTree [S28]
location_description <= 32: 1 (9/5)
location_description > 32:
:...location_description <= 33: 6 (134/109)
location_description > 33: 17 (11/7)
SubTree [S29]
primary_type = DECEPTIVE PRACTICE: 1 (32/10)
primary_type = THEFT: 8 (193/143)
SubTree [S30]
location_description <= 52: 1 (1654/1431)
location_description > 52:
:...location_description > 53: 7 (366/326)
location_description <= 53:
:...primary_type = DECEPTIVE PRACTICE: 1 (44/38)
primary_type = THEFT: 6 (730/661)
SubTree [S31]
location_description <= 92: 10 (12/3)
location_description > 92: 18 (114/71)
SubTree [S32]
location_description > 101: 1 (13339/11253)
location_description <= 101:
:...location_description > 99: 19 (498/430)
location_description <= 99:
:...location_description > 96: 18 (157/102)
location_description <= 96:
:...location_description <= 95: 1 (206/128)
location_description > 95: 12 (232/205)
Evaluation on training data (488358 cases):
Decision Tree
----------------
Size Errors
348 417035(85.4%) <<
Class Cases False False
Pos Neg
----- ----- ----- -----
1 32320 75133 12783
2 20764 1717 20547
3 20127 25258 16702
4 23909 2788 23609
5 18737 12496 17341
6 27195 9451 25880
7 22712 17537 20083
8 30292 88386 20639
9 21249 6165 20672
10 21641 2931 21139
11 32073 73020 17631
12 26996 50823 21783
14 20450 3969 20093
15 17498 730 17356
16 16846 774 14487
17 14975 314 14912
18 32110 11928 27449
19 25431 28462 21636
20 9202 56 9195
22 14605 101 14588
24 14664 1050 14379
25 24550 3929 24126
31 12 17 5
Attribute usage:
100.00% primary_type
100.00% location_description
42.20% arrest
Time: 0.5 secs
#Plotting the tree
plot(tree_result,faclen=10, clip.facs=TRUE,subtree=NULL, tweak=1, digits=2)

## PREDICTION
#Prediction of new cases from the test dataset
predictions <- predict(tree_result, newdata = test_c50, type ="class")
#table(prediction=predictions, real= crime_test_c50$primary_type)
#crime_test_c50$primary_type <- factor(crime_test_c50$primary_type)
error_classification <- mean(predictions != test_c50$district)
paste("The classification error in test set is:", 100*error_classification, "%",
sum(predictions==test_c50$district),
"correct classified cases from", length(predictions))
[1] "The classification error in test set is: 90.6715592723341 % 11389 correct classified cases from 122089"
pred_train <- predict(tree_result, newdata = train_c50)
#confusionMatrix(pred_train, crime_train$district)
#pred_train<-round(pred_train)
#table(prediction=pred_train, real= crime_train_c50$arrest)
error_classification <- mean(pred_train != train_c50$district)
paste("The classification error in train set is:", 100*error_classification, "%",
sum(pred_train==train_c50$district),
"correct classified cases from", length(pred_train))
[1] "The classification error in train set is: 85.3953452180572 % 71323 correct classified cases from 488358"
#Creating the decision tree algorithm C4.5
tree_result <- C5.0(arrest ~ ., data=train_c50, control = C5.0Control(noGlobalPruning = FALSE, CF= 0.9)) #Higher CF less prunning
summary(tree_result)
#Plotting the tree
plot(tree_result,faclen=10, clip.facs=TRUE,subtree=NULL, tweak=1, digits=2)
## PREDICTION
#Prediction of new cases from the test dataset
predictions <- predict(tree_result, newdata = test_c50, type ="class")
#table(prediction=predictions, real= crime_test_c50$primary_type)
#crime_test_c50$primary_type <- factor(crime_test_c50$primary_type)
error_classification <- mean(predictions != test_c50$arrest)
paste("The classification error in test set is:", 100*error_classification, "%",
sum(predictions==test_c50$arrest),
"correct classified cases from", length(predictions))
pred_train <- predict(tree_result, newdata = train_c50)
#confusionMatrix(pred_train, crime_train$district)
#pred_train<-round(pred_train)
#table(prediction=pred_train, real= crime_train_c50$arrest)
error_classification <- mean(pred_train != train_c50$arrest)
paste("The classification error in train set is:", 100*error_classification, "%",
sum(pred_train==train_c50$arrest),
"correct classified cases from", length(pred_train))
#levels(chicago_crime$location_description)[1] = "None"
## Creating a training and test datasets
set.seed(1234)
#assault <- subset(assault, select=-c(location_description))
#assault_tr <- subset(assault_tr, select=-c(location_description))
assault_tr <- subset(assault_tr, district=="3" | district == "4" | district == "5" | district=="6" | district == "7" | district=="8" | district == "1" | district == "18" | district == "9" | district=="10" | district == "22" | district == "15" )
assault <- subset(assault, district=="3" | district == "4" | district == "5" | district=="6" | district == "7" | district=="8" | district == "1" | district == "18" | district == "9" | district=="10" | district == "22" | district == "15" )
#train_c50<- subset(assault_tr, select=-c(case_number,block,ward,description,day,month,latitude,longitude))
#test_c50<- subset(assault, select=-c(case_number,block,ward,description,day,month,latitude,longitude))
crime_split_c50<- initial_split(subset(assault_tr, select=-c(case_number,block,ward,description,day,month,latitude,longitude)), prop=0.8)
train_c50<- training(crime_split_c50)
test_c50<- testing(crime_split_c50)
train_c50$location_description <- as.factor(train_c50$location_description)
test_c50$location_description <- as.factor(test_c50$location_description)
#train_c50$arrest <- as.numeric(train_c50$arrest, unique(train_c50$arrest))
#test_c50$arrest <- as.numeric(test_c50$arrest, unique(test_c50$arrest))
#train_c50$primary_type <- as.numeric(train_c50$primary_type, unique(train_c50$primary_type))
#test_c50$primary_type <- as.numeric(test_c50$primary_type, unique(test_c50$primary_type))
train_c50$location_description <- as.numeric(train_c50$location_description, unique(train_c50$location_description))
test_c50$location_description <- as.numeric(test_c50$location_description, unique(test_c50$location_description))
#train_c50$district <- as.numeric(train_c50$district, unique(train_c50$district))
#test_c50$district <- as.numeric(test_c50$district, unique(test_c50$district))
train_c50$arrest <- as.factor(train_c50$arrest)
test_c50$arrest <- as.factor(test_c50$arrest)
train_c50$district <- as.factor(train_c50$district)
test_c50$district <- as.factor(test_c50$district)
train_c50$district <- factor(train_c50$district)
test_c50$district <- factor(test_c50$district)
#train_c50$primary_type <- as.factor(train_c50$primary_type)
#test_c50$primary_type <- as.factor(test_c50$primary_type)
#Creating the decision tree algorithm C4.5
tree_result <- C5.0(district ~ ., data=train_c50, control = C5.0Control(noGlobalPruning = FALSE, CF= 0.0001)) #Higher CF less prunning
summary(tree_result)
Call:
C5.0.formula(formula = district ~ ., data = train_c50, control = C5.0Control(noGlobalPruning = FALSE, CF = 1e-04))
C5.0 [Release 2.07 GPL Edition] Fri May 8 13:51:43 2020
-------------------------------
Class specified by attribute `outcome'
Read 21338 cases (4 attributes) from undefined.data
Decision tree:
location_description <= 13:
:...location_description <= 12: 8 (529/437)
: location_description > 12: 3 (2139/1703)
location_description > 13:
:...location_description <= 67:
:...location_description <= 28:
: :...location_description <= 25: 18 (182/150)
: : location_description > 25: 5 (267/200)
: location_description > 28:
: :...location_description > 55:
: :...location_description <= 56: 10 (127/102)
: : location_description > 56: 1 (1376/1111)
: location_description <= 55:
: :...location_description <= 51: 1 (1383/1125)
: location_description > 51:
: :...location_description <= 52: 6 (561/464)
: location_description > 52:
: :...location_description <= 53: 1 (130/72)
: location_description > 53: 6 (264/229)
location_description > 67:
:...location_description <= 75:
:...location_description <= 71: 4 (622/542)
: location_description > 71: 5 (3744/3222)
location_description > 75:
:...location_description <= 76: 1 (644/505)
location_description > 76:
:...location_description <= 81: 4 (1480/1288)
location_description > 81:
:...location_description > 83: 9 (4532/3983)
location_description <= 83:
:...location_description <= 82: 4 (2819/2481)
location_description > 82: 1 (539/441)
Evaluation on training data (21338 cases):
Decision Tree
----------------
Size Errors
17 18055(84.6%) <<
(a) (b) (c) (d) (e) (f) (g) (h) (i) (j) (k) (l) <-classified as
---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
818 43 245 87 33 10 262 5 24 (a): class 1
245 436 444 287 86 36 360 1 12 (b): class 3
339 252 610 525 69 56 482 22 12 (c): class 4
203 107 432 589 55 27 333 8 10 (d): class 5
441 334 514 419 132 42 417 20 (e): class 6
297 210 468 526 128 56 465 18 9 (f): class 7
396 141 525 382 53 92 492 17 20 (g): class 8
303 129 402 307 81 74 549 19 (h): class 9
221 173 461 267 47 60 432 25 9 (i): class 10
199 213 324 236 46 33 289 17 6 (j): class 15
439 72 221 142 47 18 206 14 32 (k): class 18
171 29 275 244 48 25 245 9 (l): class 22
Attribute usage:
100.00% location_description
Time: 0.0 secs
#Plotting the tree
plot(tree_result,subtree=NULL)

## PREDICTION
#Prediction of new cases from the test dataset
predictions <- predict(tree_result, newdata = test_c50, type ="class")
#table(prediction=predictions, real= crime_test_c50$primary_type)
#crime_test_c50$primary_type <- factor(crime_test_c50$primary_type)
error_classification <- mean(predictions != test_c50$district)
paste("The classification error in test set is:", 100*error_classification, "%",
sum(predictions==test_c50$district),
"correct classified cases from", length(predictions))
[1] "The classification error in test set is: 91.1886014248219 % 470 correct classified cases from 5334"
pred_train <- predict(tree_result, newdata = train_c50)
#confusionMatrix(pred_train, crime_train$district)
#pred_train<-round(pred_train)
#table(prediction=pred_train, real= crime_train_c50$arrest)
error_classification <- mean(pred_train != train_c50$district)
paste("The classification error in train set is:", 100*error_classification, "%",
sum(pred_train==train_c50$district),
"correct classified cases from", length(pred_train))
[1] "The classification error in train set is: 84.6143031211922 % 3283 correct classified cases from 21338"
#levels(chicago_crime$location_description)[1] = "None"
## Creating a training and test datasets
set.seed(1234)
#criminal_damage <- subset(criminal_damage, select=-c(location_description))
#criminal_damage_tr <- subset( criminal_damage_tr, select=-c(location_description))
criminal_damage_tr <- subset(criminal_damage_tr, district=="3" | district == "4" | district == "5" | district=="6" | district == "7" | district=="8" | district == "1" | district == "18" | district == "9" | district=="20" | district == "25" | district == "11")
criminal_damage <- subset(criminal_damage, district=="3" | district == "4" | district == "5" | district=="6" | district == "7" | district=="8" | district == "1" | district == "18" | district == "9" | district=="20" | district == "25" | district == "11")
train_c50<- subset(criminal_damage_tr, select=-c(case_number,block,ward,description,day,month,latitude,longitude))
test_c50<- subset(criminal_damage, select=-c(case_number,block,ward,description,day,month,latitude,longitude))
#crime_split_c50<- initial_split(subset(chicago_crime_subset_tr, select=-c(case_number,block,ward,description,day,month,latitude,longitude)), prop=0.8)
#train_c50<- training(crime_split_c50)
#test_c50<- testing(crime_split_c50)
train_c50$location_description <- as.factor(train_c50$location_description)
test_c50$location_description <- as.factor(test_c50$location_description)
#train_c50$arrest <- as.numeric(train_c50$arrest, unique(train_c50$arrest))
#test_c50$arrest <- as.numeric(test_c50$arrest, unique(test_c50$arrest))
#train_c50$primary_type <- as.numeric(train_c50$primary_type, unique(train_c50$primary_type))
#test_c50$primary_type <- as.numeric(test_c50$primary_type, unique(test_c50$primary_type))
#train_c50$location_description <- as.numeric(train_c50$location_description, unique(train_c50$location_description))
#test_c50$location_description <- as.numeric(test_c50$location_description, unique(test_c50$location_description))
#train_c50$district <- as.numeric(train_c50$district, unique(train_c50$district))
#test_c50$district <- as.numeric(test_c50$district, unique(test_c50$district))
train_c50$arrest <- as.factor(train_c50$arrest)
test_c50$arrest <- as.factor(test_c50$arrest)
train_c50$district <- as.factor(train_c50$district)
test_c50$district <- as.factor(test_c50$district)
train_c50$district <- factor(train_c50$district)
test_c50$district <- factor(test_c50$district)
#train_c50$primary_type <- as.factor(train_c50$primary_type)
#test_c50$primary_type <- as.factor(test_c50$primary_type)
#Creating the decision tree algorithm C4.5
tree_result <- C5.0(district ~ ., data=train_c50, control = C5.0Control(noGlobalPruning = FALSE, CF= 0.001)) #Higher CF less prunning
summary(tree_result)
Call:
C5.0.formula(formula = district ~ ., data = train_c50, control = C5.0Control(noGlobalPruning = FALSE, CF = 0.001))
C5.0 [Release 2.07 GPL Edition] Wed May 6 16:43:00 2020
-------------------------------
Class specified by attribute `outcome'
Read 45588 cases (4 attributes) from undefined.data
Decision tree:
location_description in {ABANDONED BUILDING,
: AIRPORT BUILDING NON-TERMINAL - NON-SECURE AREA,
: AIRPORT BUILDING NON-TERMINAL - SECURE AREA,
: AIRPORT EXTERIOR - NON-SECURE AREA,
: AIRPORT EXTERIOR - SECURE AREA,AIRPORT PARKING LOT,
: AIRPORT TERMINAL LOWER LEVEL - NON-SECURE AREA,
: AIRPORT TERMINAL LOWER LEVEL - SECURE AREA,
: AIRPORT TERMINAL UPPER LEVEL - NON-SECURE AREA,
: AIRPORT TERMINAL UPPER LEVEL - SECURE AREA,
: ANIMAL HOSPITAL,APPLIANCE STORE,CHA APARTMENT,
: CHA HALLWAY/STAIRWELL/ELEVATOR,
: CHA PARKING LOT/GROUNDS,
: CHURCH/SYNAGOGUE/PLACE OF WORSHIP,
: COIN OPERATED MACHINE,CREDIT UNION,
: CTA GARAGE / OTHER PROPERTY,CTA TRACKS - RIGHT OF WAY,
: CTA TRAIN,DRIVEWAY - RESIDENTIAL,
: FACTORY/MANUFACTURING BUILDING,FIRE STATION,
: FOREST PRESERVE,HIGHWAY/EXPRESSWAY,
: OTHER RAILROAD PROP / TRAIN DEPOT,PAWN SHOP,POOL ROOM,
: RESIDENCE,RESIDENCE PORCH/HALLWAY,RESIDENCE-GARAGE,
: RESIDENTIAL YARD (FRONT/BACK),SAVINGS AND LOAN,
: SCHOOL PUBLIC BUILDING,SCHOOL PUBLIC GROUNDS,
: VACANT LOT/LAND,
: VEHICLE - DELIVERY TRUCK}: 8 (14667/12108)
location_description in {APARTMENT,CTA BUS,CURRENCY EXCHANGE,
: GAS STATION}: 3 (5871/4778)
location_description in {ALLEY,ATHLETIC CLUB,ATM (AUTOMATIC TELLER MACHINE),
: AUTO / BOAT / RV DEALERSHIP,BANK,BAR OR TAVERN,
: BARBERSHOP,BOAT/WATERCRAFT,BOWLING ALLEY,BRIDGE,
: CAR WASH,CEMETARY,CLEANING STORE,
: COLLEGE/UNIVERSITY GROUNDS,
: COLLEGE/UNIVERSITY RESIDENCE HALL,
: COMMERCIAL / BUSINESS OFFICE,CONSTRUCTION SITE,
: CONVENIENCE STORE,CTA BUS STOP,CTA PLATFORM,
: CTA STATION,DAY CARE CENTER,DEPARTMENT STORE,
: DRUG STORE,FEDERAL BUILDING,
: GOVERNMENT BUILDING/PROPERTY,GROCERY FOOD STORE,
: HOSPITAL BUILDING/GROUNDS,HOTEL/MOTEL,
: JAIL / LOCK-UP FACILITY,
: LAKEFRONT/WATERFRONT/RIVERBANK,LIBRARY,
: MEDICAL/DENTAL OFFICE,MOVIE HOUSE/THEATER,
: NURSING HOME/RETIREMENT HOME,OTHER,
: OTHER COMMERCIAL TRANSPORTATION,PARK PROPERTY,
: PARKING LOT/GARAGE(NON.RESID.),
: POLICE FACILITY/VEH PARKING LOT,RESTAURANT,
: SCHOOL PRIVATE BUILDING,SCHOOL PRIVATE GROUNDS,
: SIDEWALK,SMALL RETAIL STORE,SPORTS ARENA/STADIUM,
: STREET,TAVERN/LIQUOR STORE,TAXICAB,
: VEHICLE - OTHER RIDE SERVICE,
: VEHICLE - OTHER RIDE SHARE SERVICE (),
: VEHICLE NON-COMMERCIAL,VEHICLE-COMMERCIAL,WAREHOUSE}:
:...location_description in {ALLEY,CAR WASH,DAY CARE CENTER,
: NURSING HOME/RETIREMENT HOME,SPORTS ARENA/STADIUM,
: STREET,VEHICLE NON-COMMERCIAL}: 8 (17364/15004)
location_description in {ATHLETIC CLUB,ATM (AUTOMATIC TELLER MACHINE),
AUTO / BOAT / RV DEALERSHIP,BANK,BAR OR TAVERN,
BARBERSHOP,BOAT/WATERCRAFT,BOWLING ALLEY,BRIDGE,
CEMETARY,CLEANING STORE,
COLLEGE/UNIVERSITY GROUNDS,
COLLEGE/UNIVERSITY RESIDENCE HALL,
COMMERCIAL / BUSINESS OFFICE,CONSTRUCTION SITE,
CONVENIENCE STORE,CTA BUS STOP,CTA PLATFORM,
CTA STATION,DEPARTMENT STORE,DRUG STORE,
FEDERAL BUILDING,GOVERNMENT BUILDING/PROPERTY,
GROCERY FOOD STORE,HOSPITAL BUILDING/GROUNDS,
HOTEL/MOTEL,JAIL / LOCK-UP FACILITY,
LAKEFRONT/WATERFRONT/RIVERBANK,LIBRARY,
MEDICAL/DENTAL OFFICE,MOVIE HOUSE/THEATER,OTHER,
OTHER COMMERCIAL TRANSPORTATION,PARK PROPERTY,
PARKING LOT/GARAGE(NON.RESID.),
POLICE FACILITY/VEH PARKING LOT,RESTAURANT,
SCHOOL PRIVATE BUILDING,SCHOOL PRIVATE GROUNDS,
SIDEWALK,SMALL RETAIL STORE,TAVERN/LIQUOR STORE,
TAXICAB,VEHICLE - OTHER RIDE SERVICE,
VEHICLE - OTHER RIDE SHARE SERVICE (),
VEHICLE-COMMERCIAL,WAREHOUSE}: 1 (7686/6506)
Evaluation on training data (45588 cases):
Decision Tree
----------------
Size Errors
4 38396(84.2%) <<
(a) (b) (c) (d) (e) (f) (g) (h) (i) (j) (k) (l) <-classified as
---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
1180 65 1004 (a): class 1
451 1093 2304 (b): class 3
582 611 3429 (c): class 4
402 308 2987 (d): class 5
613 878 3080 (e): class 6
354 584 2820 (f): class 7
896 438 4919 (g): class 8
648 420 2969 (h): class 9
548 773 2873 (i): class 11
1051 96 1497 (j): class 18
341 173 835 (k): class 20
620 432 3314 (l): class 25
Attribute usage:
100.00% location_description
Time: 0.0 secs
#Plotting the tree
plot(tree_result,subtree=NULL)

## PREDICTION
#Prediction of new cases from the test dataset
predictions <- predict(tree_result, newdata = test_c50, type ="class")
Error in model.frame.default(object$Terms, newdata, na.action = na.action, :
factor location_description has new levels FARM
#levels(chicago_crime$location_description)[1] = "None"
## Creating a training and test datasets
set.seed(1234)
#deceptive_practice <- subset(deceptive_practice, select=-c(location_description))
#deceptive_practice_tr <- subset(deceptive_practice_tr, select=-c(location_description))
deceptive_practice_tr <- subset(deceptive_practice_tr, district=="19" | district == "4" | district == "25" | district=="2" | district == "24" |district == "1" | district == "18"| district == "20" | district == "9" | district=="21" | district == "25" | district == "11" )
deceptive_practice <- subset(deceptive_practice, district=="19" | district == "4" | district == "25" | district=="2" | district == "24" |district == "1" | district == "18"| district == "20" | district == "9" | district=="21" | district == "25" | district == "11" )
#train_c50<- subset(deceptive_practice_tr, select=-c(case_number,block,ward,description,day,month,latitude,longitude))
#test_c50<- subset(deceptive_practice, select=-c(case_number,block,ward,description,day,month,latitude,longitude))
crime_split_c50<- initial_split(subset(deceptive_practice_tr, select=-c(location_description,case_number,block,ward,description,day,month,latitude,longitude)), prop=0.8)
train_c50<- training(crime_split_c50)
test_c50<- testing(crime_split_c50)
#train_c50$location_description <- as.factor(train_c50$location_description)
#test_c50$location_description <- as.factor(test_c50$location_description)
#train_c50$arrest <- as.numeric(train_c50$arrest, unique(train_c50$arrest))
#test_c50$arrest <- as.numeric(test_c50$arrest, unique(test_c50$arrest))
#train_c50$primary_type <- as.numeric(train_c50$primary_type, unique(train_c50$primary_type))
#test_c50$primary_type <- as.numeric(test_c50$primary_type, unique(test_c50$primary_type))
#train_c50$location_description <- as.numeric(train_c50$location_description, unique(train_c50$location_description))
#test_c50$location_description <- as.numeric(test_c50$location_description, unique(test_c50$location_description))
#train_c50$district <- as.numeric(train_c50$district, unique(train_c50$district))
#test_c50$district <- as.numeric(test_c50$district, unique(test_c50$district))
train_c50$arrest <- as.factor(train_c50$arrest)
test_c50$arrest <- as.factor(test_c50$arrest)
train_c50$district <- as.factor(train_c50$district)
test_c50$district <- as.factor(test_c50$district)
train_c50$district <- factor(train_c50$district)
test_c50$district <- factor(test_c50$district)
#train_c50$primary_type <- as.factor(train_c50$primary_type)
#test_c50$primary_type <- as.factor(test_c50$primary_type)
#Creating the decision tree algorithm C4.5
tree_result <- C5.0(district ~ ., data=train_c50, control = C5.0Control(noGlobalPruning = FALSE, CF= 0.5)) #Higher CF less prunning
#summary(tree_result)
#Plotting the tree
plot(tree_result,subtree=NULL)

## PREDICTION
#Prediction of new cases from the test dataset
predictions <- predict(tree_result, newdata = test_c50, type ="class")
#table(prediction=predictions, real= crime_test_c50$primary_type)
#crime_test_c50$primary_type <- factor(crime_test_c50$primary_type)
error_classification <- mean(predictions != test_c50$district)
paste("The classification error in test set is:", 100*error_classification, "%",
sum(predictions==test_c50$district),
"correct classified cases from", length(predictions))
[1] "The classification error in test set is: 79.3173028417689 % 1230 correct classified cases from 5947"
pred_train <- predict(tree_result, newdata = train_c50)
#confusionMatrix(pred_train, crime_train$district)
#pred_train<-round(pred_train)
#table(prediction=pred_train, real= crime_train_c50$arrest)
error_classification <- mean(pred_train != train_c50$district)
paste("The classification error in train set is:", 100*error_classification, "%",
sum(pred_train==train_c50$district),
"correct classified cases from", length(pred_train))
[1] "The classification error in train set is: 78.8584398117014 % 5030 correct classified cases from 23792"
#levels(chicago_crime$location_description)[1] = "None"
## Creating a training and test datasets
set.seed(1234)
#narcotics <- subset(narcotics, select=-c(location_description))
#narcotics_tr <- subset(narcotics_tr, select=-c(location_description))
#narcotics_tr <- subset(narcotics_tr, district=="10" | district == "11" | district == "15" | district=="8" | district == "1" | district=="18")
#narcotics <- subset(narcotics, district=="10" | district == "11" | district == "15" | district=="8" | district == "1" | district=="18")
#train_c50<- subset(narcotics_tr, select=-c(case_number,block,ward,description,day,month,latitude,longitude))
#test_c50<- subset(narcotics, select=-c(case_number,block,ward,description,day,month,latitude,longitude))
crime_split_c50<- initial_split(subset(narcotics_tr, select=-c(location_description,case_number,block,ward,description,day,month,latitude,longitude)), prop=0.8)
train_c50<- training(crime_split_c50)
test_c50<- testing(crime_split_c50)
#train_c50$location_description <- as.factor(train_c50$location_description)
#test_c50$location_description <- as.factor(test_c50$location_description)
#train_c50$arrest <- as.numeric(train_c50$arrest, unique(train_c50$arrest))
#test_c50$arrest <- as.numeric(test_c50$arrest, unique(test_c50$arrest))
#train_c50$primary_type <- as.numeric(train_c50$primary_type, unique(train_c50$primary_type))
#test_c50$primary_type <- as.numeric(test_c50$primary_type, unique(test_c50$primary_type))
#train_c50$location_description <- as.numeric(train_c50$location_description, unique(train_c50$location_description))
#test_c50$location_description <- as.numeric(test_c50$location_description, unique(test_c50$location_description))
#train_c50$district <- as.numeric(train_c50$district, unique(train_c50$district))
#test_c50$district <- as.numeric(test_c50$district, unique(test_c50$district))
#train_c50$arrest <- as.factor(train_c50$arrest)
#test_c50$arrest <- as.factor(test_c50$arrest)
train_c50$district <- as.factor(train_c50$district)
test_c50$district <- as.factor(test_c50$district)
train_c50$district <- factor(train_c50$district)
test_c50$district <- factor(test_c50$district)
#train_c50$primary_type <- as.factor(train_c50$primary_type)
#test_c50$primary_type <- as.factor(test_c50$primary_type)
#Creating the decision tree algorithm C4.5
tree_result <- C5.0(district ~ ., data=train_c50, control = C5.0Control(noGlobalPruning = FALSE, CF= 0.01)) #Higher CF less prunning
summary(tree_result)
Call:
C5.0.formula(formula = district ~ ., data = train_c50, control = C5.0Control(noGlobalPruning = FALSE, CF = 0.01))
C5.0 [Release 2.07 GPL Edition] Fri May 8 13:54:54 2020
-------------------------------
Class specified by attribute `outcome'
Read 16510 cases (3 attributes) from undefined.data
Decision tree:
11 (16510/7867)
Evaluation on training data (16510 cases):
Decision Tree
----------------
Size Errors
1 7867(47.6%) <<
(a) (b) (c) (d) (e) (f) <-classified as
---- ---- ---- ---- ---- ----
364 (a): class 1
1199 (b): class 8
3178 (c): class 10
8643 (d): class 11
2769 (e): class 15
357 (f): class 18
Time: 0.0 secs
#Plotting the tree
plot(tree_result,subtree=NULL)

## PREDICTION
#Prediction of new cases from the test dataset
predictions <- predict(tree_result, newdata = test_c50, type ="class")
#table(prediction=predictions, real= crime_test_c50$primary_type)
#crime_test_c50$primary_type <- factor(crime_test_c50$primary_type)
error_classification <- mean(predictions != test_c50$district)
paste("The classification error in test set is:", 100*error_classification, "%",
sum(predictions==test_c50$district),
"correct classified cases from", length(predictions))
[1] "The classification error in test set is: 48.1948146353283 % 2138 correct classified cases from 4127"
pred_train <- predict(tree_result, newdata = train_c50)
#confusionMatrix(pred_train, crime_train$district)
#pred_train<-round(pred_train)
#table(prediction=pred_train, real= crime_train_c50$arrest)
error_classification <- mean(pred_train != train_c50$district)
paste("The classification error in train set is:", 100*error_classification, "%",
sum(pred_train==train_c50$district),
"correct classified cases from", length(pred_train))
[1] "The classification error in train set is: 47.6499091459721 % 8643 correct classified cases from 16510"
## Creating a training and test datasets
set.seed(1234)
#robbery <- subset(robbery, select=-c(location_description))
#robbery_tr <- subset(robbery_tr, select=-c(location_description))
robbery_tr <- subset(robbery_tr, district=="6" | district == "11" | district == "15" | district=="8" | district == "1" | district=="18"| district=="9" | district == "5" | district=="4")
robbery <- subset(robbery, district=="6" | district == "11" | district == "15" | district=="8" | district == "1" | district=="18"| district=="9" | district == "5" | district=="4")
#robbery$location_description <- gsub("PARKING LOT","PARKING",robbery$location_description)
#robbery_tr$location_description <- gsub("PARKING LOT","PARKING",robbery_tr$location_description)
#robbery$location_description <- gsub("PARKINGGARAGE(NON.RESID.)","PARKING",robbery$location_description)
#robbery_tr$location_description <- gsub("PARKINGGARAGE(NON.RESID.)","PARKING",robbery_tr$location_description)
train_c50<- subset(robbery_tr, select=-c(case_number,block,ward,description,day,month,latitude,longitude))
test_c50<- subset(robbery, select=-c(case_number,block,ward,description,day,month,latitude,longitude))
#crime_split_c50<- initial_split(subset(chicago_crime_subset_tr, select=-c(case_number,block,ward,description,day,month,latitude,longitude)), prop=0.8)
#train_c50<- training(crime_split_c50)
#test_c50<- testing(crime_split_c50)
train_c50$location_description <- as.factor(train_c50$location_description)
test_c50$location_description <- as.factor(test_c50$location_description)
train_c50$location_description <- factor(train_c50$location_description)
test_c50$location_description <- factor(test_c50$location_description)
#train_c50$arrest <- as.numeric(train_c50$arrest, unique(train_c50$arrest))
#test_c50$arrest <- as.numeric(test_c50$arrest, unique(test_c50$arrest))
#train_c50$primary_type <- as.numeric(train_c50$primary_type, unique(train_c50$primary_type))
#test_c50$primary_type <- as.numeric(test_c50$primary_type, unique(test_c50$primary_type))
train_c50$location_description <- as.numeric(train_c50$location_description, unique(train_c50$location_description))
test_c50$location_description <- as.numeric(test_c50$location_description, unique(test_c50$location_description))
#train_c50$district <- as.numeric(train_c50$district, unique(train_c50$district))
#test_c50$district <- as.numeric(test_c50$district, unique(test_c50$district))
train_c50$arrest <- as.factor(train_c50$arrest)
test_c50$arrest <- as.factor(test_c50$arrest)
train_c50$district <- as.factor(train_c50$district)
test_c50$district <- as.factor(test_c50$district)
train_c50$district <- factor(train_c50$district)
test_c50$district <- factor(test_c50$district)
#train_c50$primary_type <- as.factor(train_c50$primary_type)
#test_c50$primary_type <- as.factor(test_c50$primary_type)
#Creating the decision tree algorithm C4.5
tree_result <- C5.0(district ~., data=train_c50, control = C5.0Control(noGlobalPruning = TRUE, CF= 0.000001)) #Higher CF less prunning
summary(tree_result)
Call:
C5.0.formula(formula = district ~ ., data = train_c50, control = C5.0Control(noGlobalPruning = TRUE, CF = 1e-06))
C5.0 [Release 2.07 GPL Edition] Wed May 6 17:02:50 2020
-------------------------------
Class specified by attribute `outcome'
Read 41594 cases (4 attributes) from undefined.data
Decision tree:
arrest = True:
:...location_description > 73:
: :...location_description > 77:
: : :...location_description <= 85: 1 (1478/1201)
: : : location_description > 85: 11 (738/598)
: : location_description <= 77:
: : :...location_description > 75: 8 (359/272)
: : location_description <= 75:
: : :...location_description <= 74: 5 (550/441)
: : location_description > 74: 11 (170/134)
: location_description <= 73:
: :...location_description > 54:
: :...location_description > 66:
: : :...location_description <= 69: 1 (139/100)
: : : location_description > 69: 6 (451/340)
: : location_description <= 66:
: : :...location_description > 56: 1 (648/338)
: : location_description <= 56:
: : :...location_description <= 55: 1 (2/1)
: : location_description > 55: 18 (101/38)
: location_description <= 54:
: :...location_description <= 37:
: :...location_description > 12: 1 (885/655)
: : location_description <= 12:
: : :...location_description > 6: 6 (469/380)
: : location_description <= 6:
: : :...location_description <= 2: 5 (58/39)
: : location_description > 2: 8 (6)
: location_description > 37:
: :...location_description > 51: 11 (1040/784)
: location_description <= 51:
: :...location_description > 39: 1 (343/242)
: location_description <= 39:
: :...location_description <= 38: 1 (70/41)
: location_description > 38: 6 (297/185)
arrest = False:
:...location_description > 82: 11 (11217/9162)
location_description <= 82:
:...location_description > 70: 8 (11291/8218)
location_description <= 70:
:...location_description <= 11:
:...location_description <= 9: 11 (1201/932)
: location_description > 9: 6 (4744/3827)
location_description > 11:
:...location_description <= 25:
:...location_description > 22: 5 (188/108)
: location_description <= 22:
: :...location_description > 17: 8 (85/69)
: location_description <= 17:
: :...location_description <= 16: 1 (139/102)
: location_description > 16: 18 (60/32)
location_description > 25:
:...location_description > 63: 8 (1904/1546)
location_description <= 63:
:...location_description > 54:
:...location_description <= 58: 18 (159/89)
: location_description > 58: 11 (67/53)
location_description <= 54:
:...location_description > 46: 11 (660/489)
location_description <= 46:
:...location_description > 36: 1 (904/637)
location_description <= 36:
:...location_description > 32: 11 (584/482)
location_description <= 32:
:...location_description > 28: 18 (473/350)
location_description <= 28:
:...location_description <= 26: 11 (91/75)
location_description > 26: 8 (23/13)
Evaluation on training data (41594 cases):
Decision Tree
----------------
Size Errors
35 31973(76.9%) <<
(a) (b) (c) (d) (e) (f) (g) (h) (i) <-classified as
---- ---- ---- ---- ---- ---- ---- ---- ----
1291 28 249 649 1145 173 (a): class 1
341 102 1023 1905 1586 64 (b): class 4
315 208 314 1598 1344 36 (c): class 5
450 90 1229 1796 2295 61 (d): class 6
390 90 666 3550 1944 64 (e): class 8
416 80 722 1601 1497 42 (f): class 9
435 99 799 1081 3059 44 (g): class 11
184 45 574 699 1652 25 (h): class 15
786 54 385 789 1246 284 (i): class 18
Attribute usage:
100.00% location_description
100.00% arrest
Time: 0.0 secs
#Plotting the tree
plot(tree_result,subtree=NULL)

## PREDICTION
#Prediction of new cases from the test dataset
predictions <- predict(tree_result, newdata = test_c50, type ="class")
#table(prediction=predictions, real= crime_test_c50$primary_type)
#crime_test_c50$primary_type <- factor(crime_test_c50$primary_type)
error_classification <- mean(predictions != test_c50$district)
paste("The classification error in test set is:", 100*error_classification, "%",
sum(predictions==test_c50$district),
"correct classified cases from", length(predictions))
[1] "The classification error in test set is: 82.5898772193269 % 1971 correct classified cases from 11321"
pred_train <- predict(tree_result, newdata = train_c50)
#confusionMatrix(pred_train, crime_train$district)
#pred_train<-round(pred_train)
#table(prediction=pred_train, real= crime_train_c50$arrest)
error_classification <- mean(pred_train != train_c50$district)
paste("The classification error in train set is:", 100*error_classification, "%",
sum(pred_train==train_c50$district),
"correct classified cases from", length(pred_train))
[1] "The classification error in train set is: 76.8692599894216 % 9621 correct classified cases from 41594"
## Creating a training and test datasets
set.seed(1234)
theft <- subset(theft, select=-c(location_description))
theft_tr <- subset(theft_tr, select=-c(location_description))
theft_tr <- subset(theft_tr, district=="19" | district == "1" | district=="18"| district=="24" | district == "5" | district=="4")
theft <- subset(theft, district=="19" | district == "1" | district=="18"| district=="24" | district == "5" | district=="4")
train_c50<- subset(theft_tr, select=-c(case_number,block,ward,description,day,month,latitude,longitude))
test_c50<- subset(theft, select=-c(case_number,block,ward,description,day,month,latitude,longitude))
#crime_split_c50<- initial_split(subset(chicago_crime_subset_tr, select=-c(case_number,block,ward,description,day,month,latitude,longitude)), prop=0.8)
#train_c50<- training(crime_split_c50)
#test_c50<- testing(crime_split_c50)
train_c50$location_description <- as.factor(train_c50$location_description)
test_c50$location_description <- as.factor(test_c50$location_description)
#train_c50$arrest <- as.numeric(train_c50$arrest, unique(train_c50$arrest))
#test_c50$arrest <- as.numeric(test_c50$arrest, unique(test_c50$arrest))
#train_c50$primary_type <- as.numeric(train_c50$primary_type, unique(train_c50$primary_type))
#test_c50$primary_type <- as.numeric(test_c50$primary_type, unique(test_c50$primary_type))
train_c50$location_description <- as.numeric(train_c50$location_description, unique(train_c50$location_description))
test_c50$location_description <- as.numeric(test_c50$location_description, unique(test_c50$location_description))
#train_c50$district <- as.numeric(train_c50$district, unique(train_c50$district))
#test_c50$district <- as.numeric(test_c50$district, unique(test_c50$district))
#train_c50$arrest <- as.factor(train_c50$arrest)
#test_c50$arrest <- as.factor(test_c50$arrest)
train_c50$district <- as.factor(train_c50$district)
test_c50$district <- as.factor(test_c50$district)
train_c50$district <- factor(train_c50$district)
test_c50$district <- factor(test_c50$district)
#train_c50$primary_type <- as.factor(train_c50$primary_type)
#test_c50$primary_type <- as.factor(test_c50$primary_type)
#Creating the decision tree algorithm C4.5
tree_result <- C5.0(district ~ ., data=train_c50, control = C5.0Control(noGlobalPruning = FALSE, CF= 0.01)) #Higher CF less prunning
#summary(tree_result)
#Plotting the tree
plot(tree_result,subtree=NULL)
## PREDICTION
#Prediction of new cases from the test dataset
predictions <- predict(tree_result, newdata = test_c50, type ="class")
#table(prediction=predictions, real= crime_test_c50$primary_type)
#crime_test_c50$primary_type <- factor(crime_test_c50$primary_type)
error_classification <- mean(predictions != test_c50$district)
paste("The classification error in test set is:", 100*error_classification, "%",
sum(predictions==test_c50$district),
"correct classified cases from", length(predictions))
pred_train <- predict(tree_result, newdata = train_c50)
#confusionMatrix(pred_train, crime_train$district)
#pred_train<-round(pred_train)
#table(prediction=pred_train, real= crime_train_c50$arrest)
error_classification <- mean(pred_train != train_c50$district)
paste("The classification error in train set is:", 100*error_classification, "%",
sum(pred_train==train_c50$district),
"correct classified cases from", length(pred_train))
set.seed(1234)
#violent_crime <- subset(violent_crime, select=-c(location_description))
#violent_tr_crime <- subset(violent_tr_crime, select=-c(location_description))
violent_tr_crime <- subset(violent_tr_crime, district=="6" | district == "11" | district == "15" | district=="8" | district == "1" | district=="18"| district=="9" | district == "5" | district=="4" | district == "19"| district == "20" | district == "10" | district=="21" | district == "25" | district == "2")
violent_crime <- subset(violent_crime, district=="6" | district == "11" | district == "15" | district=="8" | district == "1" | district=="18"| district=="9" | district == "5" | district=="4" | district == "19"| district == "20" | district == "10" | district=="21" | district == "25" | district == "2")
train_c50<- subset(violent_tr_crime, select=-c(case_number,block,ward,description,day,month,latitude,longitude))
test_c50<- subset(violent_crime, select=-c(case_number,block,ward,description,day,month,latitude,longitude))
#crime_split_c50<- initial_split(subset(chicago_crime_subset_tr, select=-c(case_number,block,ward,description,day,month,latitude,longitude)), prop=0.8)
#train_c50<- training(crime_split_c50)
#test_c50<- testing(crime_split_c50)
train_c50$location_description <- as.factor(train_c50$location_description)
test_c50$location_description <- as.factor(test_c50$location_description)
#train_c50$arrest <- as.numeric(train_c50$arrest, unique(train_c50$arrest))
#test_c50$arrest <- as.numeric(test_c50$arrest, unique(test_c50$arrest))
#train_c50$primary_type <- as.numeric(train_c50$primary_type, unique(train_c50$primary_type))
#test_c50$primary_type <- as.numeric(test_c50$primary_type, unique(test_c50$primary_type))
#train_c50$location_description <- as.numeric(train_c50$location_description, unique(train_c50$location_description))
#test_c50$location_description <- as.numeric(test_c50$location_description, unique(test_c50$location_description))
#train_c50$district <- as.numeric(train_c50$district, unique(train_c50$district))
#test_c50$district <- as.numeric(test_c50$district, unique(test_c50$district))
train_c50$arrest <- as.factor(train_c50$arrest)
test_c50$arrest <- as.factor(test_c50$arrest)
train_c50$district <- as.factor(train_c50$district)
test_c50$district <- as.factor(test_c50$district)
train_c50$district <- factor(train_c50$district)
test_c50$district <- factor(test_c50$district)
#train_c50$primary_type <- as.factor(train_c50$primary_type)
#test_c50$primary_type <- as.factor(test_c50$primary_type)
#Creating the decision tree algorithm C4.5
tree_result <- C5.0(district ~ ., data=train_c50, trials = 10,control = C5.0Control(noGlobalPruning = FALSE, CF= 0.000001)) #Higher CF less prunning
#summary(tree_result)
#Plotting the tree
plot(tree_result,subtree=NULL,trial=9)
Only 1 trials are in the model. Setting 'trial' to 0 (the plot code is zero-based).

## PREDICTION
#Prediction of new cases from the test dataset
predictions <- predict(tree_result, newdata = test_c50, type ="class")
Error in model.frame.default(object$Terms, newdata, na.action = na.action, :
factor location_description has new levels , ATM (AUTOMATIC TELLER MACHINE), CHA PLAY LOT, HORSE STABLE, TRAILER, VEHICLE - DELIVERY TRUCK, VEHICLE-COMMERCIAL - TROLLEY BUS
set.seed(1234)
#weapons_violation <- subset(weapons_violation, select=-c(location_description))
#weapons_violation_tr <- subset(weapons_violation_tr, select=-c(location_description))
weapons_violation_tr <- subset(weapons_violation_tr, district=="6" | district == "11" | district == "7" | district=="8" | district == "1" | district=="18" | district == "5" | district=="4")
weapons_violation <- subset(weapons_violation, district=="6" | district == "11" | district == "7" | district=="8" | district == "1" | district=="18" | district == "5" | district=="4")
train_c50<- subset(weapons_violation_tr, select=-c(case_number,block,ward,description,day,month,latitude,longitude))
test_c50<- subset(weapons_violation, select=-c(case_number,block,ward,description,day,month,latitude,longitude))
#crime_split_c50<- initial_split(subset(chicago_crime_subset_tr, select=-c(case_number,block,ward,description,day,month,latitude,longitude)), prop=0.8)
#train_c50<- training(crime_split_c50)
#test_c50<- testing(crime_split_c50)
train_c50$location_description <- as.factor(train_c50$location_description)
test_c50$location_description <- as.factor(test_c50$location_description)
#train_c50$arrest <- as.numeric(train_c50$arrest, unique(train_c50$arrest))
#test_c50$arrest <- as.numeric(test_c50$arrest, unique(test_c50$arrest))
#train_c50$primary_type <- as.numeric(train_c50$primary_type, unique(train_c50$primary_type))
#test_c50$primary_type <- as.numeric(test_c50$primary_type, unique(test_c50$primary_type))
train_c50$location_description <- as.numeric(train_c50$location_description, unique(train_c50$location_description))
test_c50$location_description <- as.numeric(test_c50$location_description, unique(test_c50$location_description))
#train_c50$district <- as.numeric(train_c50$district, unique(train_c50$district))
#test_c50$district <- as.numeric(test_c50$district, unique(test_c50$district))
#train_c50$arrest <- as.factor(train_c50$arrest)
#test_c50$arrest <- as.factor(test_c50$arrest)
train_c50$district <- as.factor(train_c50$district)
test_c50$district <- as.factor(test_c50$district)
train_c50$district <- factor(train_c50$district)
test_c50$district <- factor(test_c50$district)
#train_c50$primary_type <- as.factor(train_c50$primary_type)
#test_c50$primary_type <- as.factor(test_c50$primary_type)
#Creating the decision tree algorithm C4.5
tree_result <- C5.0(district ~ ., data=train_c50, control = C5.0Control(noGlobalPruning = FALSE, CF= 0.01)) #Higher CF less prunning
#summary(tree_result)
#Plotting the tree
plot(tree_result,subtree=NULL)
## PREDICTION
#Prediction of new cases from the test dataset
predictions <- predict(tree_result, newdata = test_c50, type ="class")
#table(prediction=predictions, real= crime_test_c50$primary_type)
#crime_test_c50$primary_type <- factor(crime_test_c50$primary_type)
error_classification <- mean(predictions != test_c50$district)
paste("The classification error in test set is:", 100*error_classification, "%",
sum(predictions==test_c50$district),
"correct classified cases from", length(predictions))
pred_train <- predict(tree_result, newdata = train_c50)
#confusionMatrix(pred_train, crime_train$district)
#pred_train<-round(pred_train)
#table(prediction=pred_train, real= crime_train_c50$arrest)
error_classification <- mean(pred_train != train_c50$district)
paste("The classification error in train set is:", 100*error_classification, "%",
sum(pred_train==train_c50$district),
"correct classified cases from", length(pred_train))
#Tunning the m number of predictors
tuning_rf_mtry <- function(df, y, ntree = 100){
require(dplyr)
max_predictors <- ncol(df) - 1
n_predictors <- rep(NA, max_predictors)
oob_err_rate <- rep(NA, max_predictors)
for (i in 1:max_predictors) {
set.seed(123)
f <- formula(paste(y,"~ ."))
model_rf <- randomForest(formula = f, data = df, mtry = i, ntree = ntree)
n_predictors[i] <- i
oob_err_rate[i] <- tail(model_rf$err.rate[,1], n = 1)
}
results <- data_frame(n_predictors, oob_err_rate)
return(results)
}
hiperparameter_mtry <- tuning_rf_mtry(df = RF_train, y = "primary_type")
Error in oob_err_rate[i] <- tail(model_rf$err.rate[, 1], n = 1) :
replacement has length zero
REDES NEURONALES
## REDES
chicago_crime_nn <- subset(chicago_crime_subset, select=-c(case_number,block,ward,day,latitude,longitude))
chicago_crime_nn_tr <- subset(chicago_crime_subset_tr, select=-c(case_number,block,ward,day,latitude,longitude))
library(kohonen) # for building the SOM map
library(caret) #for confusion matrix
#Extracting target variable
target_train <- chicago_crime_nn_tr$primary_type
chicago_crime_nn_tr <- subset(chicago_crime_nn_tr, select=-c(primary_type))
target_test <- chicago_crime_nn$primary_type
chicago_crime_nn <- subset(chicago_crime_nn, select=-c(primary_type))
chicago_crime_nn_tr$arrest <- as.factor(chicago_crime_nn_tr$arrest)
chicago_crime_nn_tr$arrest <- as.numeric(chicago_crime_nn_tr$arrest)
#chicago_crime$primary_type <- as.numeric(chicago_crime$primary_type)
chicago_crime_nn_tr$district <- as.numeric(chicago_crime_nn_tr$district)
#chicago_crime_nn_tr$district <- as.factor(chicago_crime_nn_tr$district)
chicago_crime_nn_tr$description <- as.factor(chicago_crime_nn_tr$description)
chicago_crime_nn_tr$description <- as.numeric(chicago_crime_nn_tr$description)
chicago_crime_nn_tr$location_description <- as.factor(chicago_crime_nn_tr$location_description)
chicago_crime_nn_tr$location_description <- as.numeric(chicago_crime_nn_tr$location_description)
chicago_crime_nn_tr$month <- as.numeric(chicago_crime_nn_tr$month)
#chicago_crime_nn_tr$month <- as.factor(chicago_crime_nn_tr$month)
chicago_crime_nn$arrest <- as.factor(chicago_crime_nn$arrest)
chicago_crime_nn$arrest <- as.numeric(chicago_crime_nn$arrest)
#chicago_crime_nn$primary_type <- as.numeric(chicago_crime_nn$primary_type)
chicago_crime_nn$district <- as.numeric(chicago_crime_nn$district)
#chicago_crime_nn$district <- as.factor(chicago_crime_nn$district)
chicago_crime_nn$description <- as.factor(chicago_crime_nn$description)
chicago_crime_nn$description <- as.numeric(chicago_crime_nn$description)
chicago_crime_nn$location_description <- as.factor(chicago_crime_nn$location_description)
chicago_crime_nn$location_description <- as.numeric(chicago_crime_nn$location_description)
chicago_crime_nn$month <- as.numeric(chicago_crime_nn$month)
#chicago_crime_nn$month <- as.factor(chicago_crime_nn$month)
#Scaling original data
set.seed(7)
#target_train.sc<-scale(chicago_crime_nn_tr)
#target_test.sc<-scale(chicago_crime_nn)
# creation of training and test datasets
index <- sample(nrow(chicago_crime_nn_tr), round(0.75*nrow(chicago_crime_nn_tr)))
train <- chicago_crime_nn_tr[index,]
test <- chicago_crime_nn_tr[-index,]
#train <- chicago_crime_nn_tr
train <- as.matrix(train)
#test <- chicago_crime_nn
test <- as.matrix(test)
#train_label<-target_train
#test_label<-target_test
train_label<-target_train[index]
test_label<-target_train[-index]
#main characteristics of the map
som_grid<-somgrid(xdim=8, ydim=8, topo="hexagonal")
#training the map
crime.som <- som(train[1:100000,], grid=som_grid,
rlen=100, alpha=c(0.05, 0.01),
radius= 2, keep.data=T)
# Names of the variables used
colnames(train)
[1] "description" "location_description" "arrest" "district" "month"
# main characteristics of the map
summary(crime.som)
SOM of size 8x8 with a hexagonal topology and a bubble neighbourhood function.
The number of data layers is 1.
Distance measure(s) used: sumofsquares.
Training data included: 100000 objects.
Mean distance to the closest unit in the map: 78.082.
#Showing the training process
plot(crime.som, type="changes")

#node counts
plot(crime.som, type="counts", main="Examples per Neuron")

#Codes/Weight vectors
plot(crime.som, type="codes", main="Patterns Discovered")
coolBlueHOtRed<-function(n, alpha=1){rainbow(n,end=4/6,
alpha=alpha)[n:1]}
par(mfrow=c(2,3))

plot(crime.som, type="property", property=getCodes(crime.som, 1)[,1],
main=colnames(getCodes(crime.som, 1))[1],
palette.name=coolBlueHOtRed)
plot(crime.som, type="property", property=getCodes(crime.som, 1)[,2],
main=colnames(getCodes(crime.som, 1))[2],
palette.name=coolBlueHOtRed)
plot(crime.som, type="property", property=getCodes(crime.som, 1)[,3],
main=colnames(getCodes(crime.som, 1))[3],
palette.name=coolBlueHOtRed)
plot(crime.som, type="property", property=getCodes(crime.som, 1)[,4],
main=colnames(getCodes(crime.som, 1))[4],
palette.name=coolBlueHOtRed)
plot(crime.som, type="property", property=getCodes(crime.som, 1)[,5],
main=colnames(getCodes(crime.som, 1))[5],
palette.name=coolBlueHOtRed)
#plot(crime.som, type="property", property=getCodes(crime.som, 1)[,6],
# main=colnames(getCodes(crime.som, 1))[6],
# palette.name=coolBlueHOtRed)
# Alternative easier
coolBlueHotRed<-function(n, alpha=1){rainbow(n,end=4/6,
alpha=alpha)[n:1]}
par(mfrow=c(5,3))

for (j in 1:ncol(train)) {
plot(crime.som, type="property", property=crime.som$codes[[1]][,j],
palette.name=coolBlueHotRed,
main=colnames(train)[j], cex=0.5)
}

#som.prediction <- predict(crime.som, test)
#Clustering patterns in the map
groups<-8
#Applying hierarchical clustering for grouping patterns
crime.hc=cutree(hclust(dist(crime.som$codes[[1]])), groups)
plot(crime.som, type="codes", bgcol = rainbow(groups)[crime.hc],
main="clustering the patterns discovered")
add.cluster.boundaries(crime.som,crime.hc)

#Scaling original data
set.seed(7)
#target_train.sc<-scale(chicago_crime_nn_tr)
#target_test.sc<-scale(chicago_crime_nn)
# creation of training and test datasets
#index <- sample(nrow(target_train.sc), round(0.75*nrow(crime.sc)))
#train <- target_train.sc
#test <- target_test.sc
#train <- chicago_crime_nn_tr
#test <- chicago_crime_nn
#index <- sample(nrow(chicago_crime_nn_tr), round(0.75*nrow(chicago_crime_nn_tr)))
#train <- chicago_crime_nn_tr[index,]
#test <- chicago_crime_nn_tr[-index,]
#train_label<-target_train
#test_label<-target_test
#main characteristics of the map
som_grid<-somgrid(xdim=8, ydim=8, topo="hexagonal")
set.seed(7)
kohmap <- xyf(train[1:100000,], train_label[1:100000],
grid=som_grid,
rlen=100, alpha=c(0.05, 0.01),
radius= 2, keep.data=T)
#Showing the training process
plot(kohmap, type="changes")

#Showing distribution of wine labels in neurons
plot(kohmap, type="codes", codeRendering = "lines", shape="straight",
main=c("Crime"))


plot(kohmap, type="codes", codeRendering = "lines", shape="straight",
main=c(" patterns"))


# Plotting classes in neurons
plot(kohmap, type="mapping", labels=as.numeric(train_label)+3,
col=as.numeric(train_label)+3, pch=4, main="Map of classes", palette.name = terrain.colors)

#Prediction using the training data
print("TRAINING PREDICTION")
[1] "TRAINING PREDICTION"
kohmap.predict_tr<- predict(kohmap, newdata=train, whatmap = 1)
prediction_table_tr<-table(train_label,kohmap.predict_tr$predictions[[2]])
confusionMatrix(prediction_table_tr)
Confusion Matrix and Statistics
train_label ASSAULT CRIMINAL DAMAGE DECEPTIVE PRACTICE NARCOTICS ROBBERY THEFT VIOLENT CRIME WEAPONS VIOLATION
ASSAULT 4120 0 15 0 1442 3264 23831 0
CRIMINAL DAMAGE 327 52639 1472 2 3088 322 259 120
DECEPTIVE PRACTICE 246 458 10222 0 9272 14838 4850 24
NARCOTICS 94 0 206 16574 621 9233 1396 0
ROBBERY 555 17038 1937 0 30716 8157 8735 688
THEFT 130 1345 1644 0 2375 142814 12255 0
VIOLENT CRIME 4098 56 894 70 1847 7334 45993 20
WEAPONS VIOLATION 78 3119 1 84 1459 93 774 4591
Overall Statistics
Accuracy : 0.672
95% CI : (0.6706, 0.6734)
No Information Rate : 0.4064
P-Value [Acc > NIR] : < 2.2e-16
Kappa : 0.5821
Mcnemar's Test P-Value : < 2.2e-16
Statistics by Class:
Class: ASSAULT Class: CRIMINAL DAMAGE Class: DECEPTIVE PRACTICE Class: NARCOTICS Class: ROBBERY Class: THEFT
Sensitivity 0.427032 0.7051 0.62363 0.99068 0.60441 0.7676
Specificity 0.936294 0.9854 0.93275 0.97382 0.90882 0.9347
Pos Pred Value 0.126102 0.9040 0.25613 0.58932 0.45286 0.8895
Neg Pred Value 0.986998 0.9449 0.98524 0.99964 0.94845 0.8545
Prevalence 0.021073 0.1631 0.03580 0.03654 0.11100 0.4064
Detection Rate 0.008999 0.1150 0.02233 0.03620 0.06709 0.3119
Detection Prevalence 0.071362 0.1272 0.08717 0.06143 0.14815 0.3507
Balanced Accuracy 0.681663 0.8453 0.77819 0.98225 0.75662 0.8511
Class: VIOLENT CRIME Class: WEAPONS VIOLATION
Sensitivity 0.4689 0.84347
Specificity 0.9602 0.98760
Pos Pred Value 0.7626 0.45014
Neg Pred Value 0.8689 0.99810
Prevalence 0.2143 0.01189
Detection Rate 0.1005 0.01003
Detection Prevalence 0.1317 0.02228
Balanced Accuracy 0.7145 0.91554
#Prediction using the test data
print("TEST PREDICTION")
[1] "TEST PREDICTION"
kohmap.predict<- predict(kohmap, newdata=test, whatmap = 1)
prediction_table<-table(test_label,kohmap.predict$predictions[[2]])
confusionMatrix(prediction_table)
Confusion Matrix and Statistics
test_label ASSAULT CRIMINAL DAMAGE DECEPTIVE PRACTICE NARCOTICS ROBBERY THEFT VIOLENT CRIME WEAPONS VIOLATION
ASSAULT 1293 0 11 0 482 1117 7937 0
CRIMINAL DAMAGE 100 17536 532 0 1044 86 93 38
DECEPTIVE PRACTICE 79 146 3319 0 3092 5130 1598 6
NARCOTICS 33 0 74 5598 207 3013 466 0
ROBBERY 219 5663 632 0 10195 2713 2872 242
THEFT 51 430 567 0 831 47387 4179 0
VIOLENT CRIME 1374 21 310 17 624 2447 15460 9
WEAPONS VIOLATION 35 1015 0 24 507 28 224 1506
Overall Statistics
Accuracy : 0.6703
95% CI : (0.6679, 0.6726)
No Information Rate : 0.4057
P-Value [Acc > NIR] : < 2.2e-16
Kappa : 0.58
Mcnemar's Test P-Value : NA
Statistics by Class:
Class: ASSAULT Class: CRIMINAL DAMAGE Class: DECEPTIVE PRACTICE Class: NARCOTICS Class: ROBBERY Class: THEFT
Sensitivity 0.406093 0.7068 0.60955 0.99273 0.6003 0.7653
Specificity 0.936110 0.9852 0.93170 0.97419 0.9090 0.9332
Pos Pred Value 0.119280 0.9026 0.24824 0.59610 0.4524 0.8866
Neg Pred Value 0.986662 0.9454 0.98473 0.99971 0.9478 0.8534
Prevalence 0.020863 0.1626 0.03568 0.03695 0.1113 0.4057
Detection Rate 0.008472 0.1149 0.02175 0.03668 0.0668 0.3105
Detection Prevalence 0.071030 0.1273 0.08761 0.06154 0.1477 0.3502
Balanced Accuracy 0.671101 0.8460 0.77063 0.98346 0.7547 0.8492
Class: VIOLENT CRIME Class: WEAPONS VIOLATION
Sensitivity 0.4709 0.836202
Specificity 0.9599 0.987846
Pos Pred Value 0.7630 0.451033
Neg Pred Value 0.8688 0.998024
Prevalence 0.2151 0.011801
Detection Rate 0.1013 0.009868
Detection Prevalence 0.1328 0.021879
Balanced Accuracy 0.7154 0.912024
#Prediction using the test data
print("TEST PREDICTION")
[1] "TEST PREDICTION"
kohmap.predict<- predict(kohmap, newdata=test, whatmap = 1)
prediction_table<-table(test_label,kohmap.predict$predictions[[2]])
confusionMatrix(prediction_table)
Confusion Matrix and Statistics
test_label ASSAULT CRIMINAL DAMAGE DECEPTIVE PRACTICE NARCOTICS ROBBERY THEFT VIOLENT CRIME WEAPONS VIOLATION
ASSAULT 1293 0 11 0 482 1117 7937 0
CRIMINAL DAMAGE 100 17536 532 0 1044 86 93 38
DECEPTIVE PRACTICE 79 146 3319 0 3092 5130 1598 6
NARCOTICS 33 0 74 5598 207 3013 466 0
ROBBERY 219 5663 632 0 10195 2713 2872 242
THEFT 51 430 567 0 831 47387 4179 0
VIOLENT CRIME 1374 21 310 17 624 2447 15460 9
WEAPONS VIOLATION 35 1015 0 24 507 28 224 1506
Overall Statistics
Accuracy : 0.6703
95% CI : (0.6679, 0.6726)
No Information Rate : 0.4057
P-Value [Acc > NIR] : < 2.2e-16
Kappa : 0.58
Mcnemar's Test P-Value : NA
Statistics by Class:
Class: ASSAULT Class: CRIMINAL DAMAGE Class: DECEPTIVE PRACTICE Class: NARCOTICS Class: ROBBERY Class: THEFT
Sensitivity 0.406093 0.7068 0.60955 0.99273 0.6003 0.7653
Specificity 0.936110 0.9852 0.93170 0.97419 0.9090 0.9332
Pos Pred Value 0.119280 0.9026 0.24824 0.59610 0.4524 0.8866
Neg Pred Value 0.986662 0.9454 0.98473 0.99971 0.9478 0.8534
Prevalence 0.020863 0.1626 0.03568 0.03695 0.1113 0.4057
Detection Rate 0.008472 0.1149 0.02175 0.03668 0.0668 0.3105
Detection Prevalence 0.071030 0.1273 0.08761 0.06154 0.1477 0.3502
Balanced Accuracy 0.671101 0.8460 0.77063 0.98346 0.7547 0.8492
Class: VIOLENT CRIME Class: WEAPONS VIOLATION
Sensitivity 0.4709 0.836202
Specificity 0.9599 0.987846
Pos Pred Value 0.7630 0.451033
Neg Pred Value 0.8688 0.998024
Prevalence 0.2151 0.011801
Detection Rate 0.1013 0.009868
Detection Prevalence 0.1328 0.021879
Balanced Accuracy 0.7154 0.912024
## REDES
chicago_crime_nn2 <- subset(chicago_crime_subset, select=-c(description,case_number,block,day,latitude,longitude))
chicago_crime_nn_tr2 <- subset(chicago_crime_subset_tr, select=-c(description,case_number,block,day,latitude,longitude))
library(kohonen) # for building the SOM map
library(caret) #for confusion matrix
#Extracting target variable
target_train2 <- chicago_crime_nn_tr2$primary_type
chicago_crime_nn_tr2 <- subset(chicago_crime_nn_tr2, select=-c(primary_type))
target_test2 <- chicago_crime_nn2$primary_type
chicago_crime_nn2 <- subset(chicago_crime_nn2, select=-c(primary_type))
chicago_crime_nn_tr2$arrest <- as.factor(chicago_crime_nn_tr2$arrest)
chicago_crime_nn_tr2$arrest <- as.numeric(chicago_crime_nn_tr2$arrest)
#chicago_crime$primary_type <- as.numeric(chicago_crime$primary_type)
chicago_crime_nn_tr2$district <- as.numeric(chicago_crime_nn_tr2$district)
#chicago_crime_nn_tr$district <- as.factor(chicago_crime_nn_tr$district)
#chicago_crime_nn_tr2$description <- as.factor(chicago_crime_nn_tr2$description)
#chicago_crime_nn_tr2$description <- as.numeric(chicago_crime_nn_tr2$description)
chicago_crime_nn_tr2$location_description <- as.factor(chicago_crime_nn_tr2$location_description)
chicago_crime_nn_tr2$location_description <- as.numeric(chicago_crime_nn_tr2$location_description)
chicago_crime_nn_tr2$month <- as.numeric(chicago_crime_nn_tr2$month)
chicago_crime_nn_tr$month <- as.factor(chicago_crime_nn_tr$month)
chicago_crime_nn2$arrest <- as.factor(chicago_crime_nn2$arrest)
chicago_crime_nn2$arrest <- as.numeric(chicago_crime_nn2$arrest)
#chicago_crime_nn$primary_type <- as.numeric(chicago_crime_nn$primary_type)
chicago_crime_nn2$district <- as.numeric(chicago_crime_nn2$district)
#chicago_crime_nn$district <- as.factor(chicago_crime_nn$district)
#chicago_crime_nn2$description <- as.factor(chicago_crime_nn2$description)
#chicago_crime_nn2$description <- as.numeric(chicago_crime_nn2$description)
chicago_crime_nn2$location_description <- as.factor(chicago_crime_nn2$location_description)
chicago_crime_nn2$location_description <- as.numeric(chicago_crime_nn2$location_description)
chicago_crime_nn2$month <- as.numeric(chicago_crime_nn2$month)
chicago_crime_nn$month <- as.factor(chicago_crime_nn$month)
#Scaling original data
set.seed(7)
#target_train.sc<-scale(chicago_crime_nn_tr)
#target_test.sc<-scale(chicago_crime_nn)
# creation of training and test datasets
index <- sample(nrow(chicago_crime_nn_tr2), round(0.75*nrow(chicago_crime_nn_tr2)))
train <- chicago_crime_nn_tr2[index,]
test <- chicago_crime_nn_tr2[-index,]
#train <- chicago_crime_nn_tr
train <- as.matrix(train)
#test <- chicago_crime_nn
test <- as.matrix(test)
#train_label<-target_train
#test_label<-target_test
train_label<-target_train2[index]
test_label<-target_train2[-index]
#main characteristics of the map
som_grid<-somgrid(xdim=8, ydim=8, topo="hexagonal")
#training the map
crime.som <- som(train[1:100000,], grid=som_grid,
rlen=100, alpha=c(0.05, 0.01),
radius= 2, keep.data=T)
# Names of the variables used
colnames(train)
[1] "location_description" "arrest" "district" "ward" "month"
# main characteristics of the map
summary(crime.som)
SOM of size 8x8 with a hexagonal topology and a bubble neighbourhood function.
The number of data layers is 1.
Distance measure(s) used: sumofsquares.
Training data included: 100000 objects.
Mean distance to the closest unit in the map: 31.207.
#Showing the training process
plot(crime.som, type="changes")

#node counts
plot(crime.som, type="counts", main="Examples per Neuron")

#Codes/Weight vectors
plot(crime.som, type="codes", main="Patterns Discovered")
coolBlueHOtRed<-function(n, alpha=1){rainbow(n,end=4/6,
alpha=alpha)[n:1]}
par(mfrow=c(2,3))

plot(crime.som, type="property", property=getCodes(crime.som, 1)[,1],
main=colnames(getCodes(crime.som, 1))[1],
palette.name=coolBlueHOtRed)
plot(crime.som, type="property", property=getCodes(crime.som, 1)[,2],
main=colnames(getCodes(crime.som, 1))[2],
palette.name=coolBlueHOtRed)
plot(crime.som, type="property", property=getCodes(crime.som, 1)[,3],
main=colnames(getCodes(crime.som, 1))[3],
palette.name=coolBlueHOtRed)
#plot(crime.som, type="property", property=getCodes(crime.som, 1)[,4],
# main=colnames(getCodes(crime.som, 1))[4],
# palette.name=coolBlueHOtRed)
#plot(crime.som, type="property", property=getCodes(crime.som, 1)[,5],
# main=colnames(getCodes(crime.som, 1))[5],
# palette.name=coolBlueHOtRed)
#plot(crime.som, type="property", property=getCodes(crime.som, 1)[,6],
# main=colnames(getCodes(crime.som, 1))[6],
# palette.name=coolBlueHOtRed)
# Alternative easier
coolBlueHotRed<-function(n, alpha=1){rainbow(n,end=4/6,
alpha=alpha)[n:1]}
par(mfrow=c(5,3))

for (j in 1:ncol(train)) {
plot(crime.som, type="property", property=crime.som$codes[[1]][,j],
palette.name=coolBlueHotRed,
main=colnames(train)[j], cex=0.5)
}

#Clustering patterns in the map
library(RColorBrewer)
groups<-8
#Applying hierarchical clustering for grouping patterns
crime.hc=cutree(hclust(dist(crime.som$codes[[1]])), groups)
plot(crime.som, type="codes", bgcol = brewer.pal(groups, name="YlGnBu")[crime.hc],
main="clustering the patterns discovered")
add.cluster.boundaries(crime.som,crime.hc)

#Scaling original data
set.seed(7)
#target_train.sc<-scale(chicago_crime_nn_tr)
#target_test.sc<-scale(chicago_crime_nn)
# creation of training and test datasets
#index <- sample(nrow(target_train.sc), round(0.75*nrow(crime.sc)))
#train <- target_train.sc
#test <- target_test.sc
#train <- chicago_crime_nn_tr
#test <- chicago_crime_nn
#index <- sample(nrow(chicago_crime_nn_tr), round(0.75*nrow(chicago_crime_nn_tr)))
#train <- chicago_crime_nn_tr[index,]
#test <- chicago_crime_nn_tr[-index,]
#train_label<-target_train
#test_label<-target_test
#main characteristics of the map
som_grid<-somgrid(xdim=8, ydim=8, topo="hexagonal")
set.seed(7)
kohmap <- xyf(train[1:100000,], train_label[1:100000],
grid=som_grid,
rlen=100, alpha=c(0.05, 0.01),
radius= 2, keep.data=T)
#Showing the training process
plot(kohmap, type="changes")

#Showing distribution of wine labels in neurons
plot(kohmap, type="codes", codeRendering = "lines", shape="straight",
main=c("Crime"))


plot(kohmap, type="codes", codeRendering = "lines", shape="straight",
main=c(" patterns"))


# Plotting classes in neurons
#plot(kohmap, type="mapping", labels=as.numeric(train_label)+3,
# col=as.numeric(train_label)+3, pch=4, main="Map of classes", palette.name = terrain.colors)
#Prediction using the training data
print("TRAINING PREDICTION")
[1] "TRAINING PREDICTION"
kohmap.predict_tr<- predict(kohmap, newdata=train, whatmap = 1)
prediction_table_tr<-table(train_label,kohmap.predict_tr$predictions[[2]])
confusionMatrix(prediction_table_tr)
Confusion Matrix and Statistics
train_label ASSAULT CRIMINAL DAMAGE DECEPTIVE PRACTICE NARCOTICS ROBBERY THEFT VIOLENT CRIME WEAPONS VIOLATION
ASSAULT 0 0 327 1453 5590 22496 2806 0
CRIMINAL DAMAGE 0 0 853 663 11935 44081 697 0
DECEPTIVE PRACTICE 0 0 2343 640 8667 27933 327 0
NARCOTICS 0 0 87 5353 3029 18090 1565 0
ROBBERY 0 0 1297 2509 16747 44776 2497 0
THEFT 0 0 1322 1954 12329 142118 2840 0
VIOLENT CRIME 0 0 590 3873 10745 39590 5514 0
WEAPONS VIOLATION 0 0 31 649 1778 7098 643 0
Overall Statistics
Accuracy : 0.3758
95% CI : (0.3744, 0.3772)
No Information Rate : 0.7561
P-Value [Acc > NIR] : 1
Kappa : 0.1127
Mcnemar's Test P-Value : NA
Statistics by Class:
Class: ASSAULT Class: CRIMINAL DAMAGE Class: DECEPTIVE PRACTICE Class: NARCOTICS Class: ROBBERY Class: THEFT
Sensitivity NA NA 0.342044 0.31315 0.23647 0.4105
Specificity 0.92864 0.8728 0.916700 0.94833 0.86802 0.8348
Pos Pred Value NA NA 0.058707 0.19034 0.24691 0.8851
Neg Pred Value NA NA 0.989216 0.97268 0.86135 0.3135
Prevalence 0.00000 0.0000 0.014962 0.03734 0.15468 0.7561
Detection Rate 0.00000 0.0000 0.005118 0.01169 0.03658 0.3104
Detection Prevalence 0.07136 0.1272 0.087171 0.06143 0.14815 0.3507
Balanced Accuracy NA NA 0.629372 0.63074 0.55225 0.6227
Class: VIOLENT CRIME Class: WEAPONS VIOLATION
Sensitivity 0.32648 NA
Specificity 0.87573 0.97772
Pos Pred Value 0.09142 NA
Neg Pred Value 0.97139 NA
Prevalence 0.03689 0.00000
Detection Rate 0.01204 0.00000
Detection Prevalence 0.13173 0.02228
Balanced Accuracy 0.60111 NA
#Prediction using the test data
print("TEST PREDICTION")
[1] "TEST PREDICTION"
kohmap.predict<- predict(kohmap, newdata=test, whatmap = 1)
prediction_table<-table(test_label,kohmap.predict$predictions[[2]])
confusionMatrix(prediction_table)
Confusion Matrix and Statistics
test_label ASSAULT CRIMINAL DAMAGE DECEPTIVE PRACTICE NARCOTICS ROBBERY THEFT VIOLENT CRIME WEAPONS VIOLATION
ASSAULT 0 0 91 514 1938 7375 922 0
CRIMINAL DAMAGE 0 0 300 221 3912 14800 196 0
DECEPTIVE PRACTICE 0 0 763 219 3003 9284 101 0
NARCOTICS 0 0 44 1846 972 6030 499 0
ROBBERY 0 0 413 849 5544 14908 822 0
THEFT 0 0 425 680 4163 47221 956 0
VIOLENT CRIME 0 0 185 1277 3599 13357 1844 0
WEAPONS VIOLATION 0 0 15 244 583 2289 208 0
Overall Statistics
Accuracy : 0.3749
95% CI : (0.3725, 0.3774)
No Information Rate : 0.7553
P-Value [Acc > NIR] : 1
Kappa : 0.1122
Mcnemar's Test P-Value : NA
Statistics by Class:
Class: ASSAULT Class: CRIMINAL DAMAGE Class: DECEPTIVE PRACTICE Class: NARCOTICS Class: ROBBERY Class: THEFT
Sensitivity NA NA 0.34123 0.31556 0.23379 0.4097
Specificity 0.92897 0.8727 0.91616 0.94859 0.86817 0.8334
Pos Pred Value NA NA 0.05707 0.19657 0.24601 0.8835
Neg Pred Value NA NA 0.98942 0.97204 0.86031 0.3139
Prevalence 0.00000 0.0000 0.01465 0.03833 0.15539 0.7553
Detection Rate 0.00000 0.0000 0.00500 0.01210 0.03633 0.3094
Detection Prevalence 0.07103 0.1273 0.08761 0.06154 0.14767 0.3502
Balanced Accuracy NA NA 0.62870 0.63207 0.55098 0.6215
Class: VIOLENT CRIME Class: WEAPONS VIOLATION
Sensitivity 0.33237 NA
Specificity 0.87476 0.97812
Pos Pred Value 0.09101 NA
Neg Pred Value 0.97201 NA
Prevalence 0.03635 0.00000
Detection Rate 0.01208 0.00000
Detection Prevalence 0.13277 0.02188
Balanced Accuracy 0.60357 NA
## REDES
narcotics_nn <- subset(narcotics_tr, select=-c(case_number,block,day,latitude,longitude))
library(kohonen) # for building the SOM map
library(caret) #for confusion matrix
#Extracting target variable
target_train <- narcotics_nn$district
narcotics_nn <- subset(narcotics_nn, select=-c(district))
narcotics_nn$arrest <- as.factor(narcotics_nn$arrest)
narcotics_nn$arrest <- as.numeric(narcotics_nn$arrest)
narcotics_nn$primary_type <- as.factor(narcotics_nn$primary_type)
narcotics_nn$primary_type <- as.numeric(narcotics_nn$primary_type)
#narcotics_nn$district <- as.numeric(narcotics_nn$district)
#chicago_crime_nn$district <- as.factor(chicago_crime_nn$district)
narcotics_nn$description <- as.factor(narcotics_nn$description)
narcotics_nn$description <- as.numeric(narcotics_nn$description)
narcotics_nn$location_description <- as.factor(narcotics_nn$location_description)
narcotics_nn$location_description <- as.numeric(narcotics_nn$location_description)
narcotics_nn$month <- as.numeric(narcotics_nn$month)
#Scaling original data
set.seed(7)
#target_train.sc<-scale(chicago_crime_nn_tr)
#target_test.sc<-scale(chicago_crime_nn)
# creation of training and test datasets
index <- sample(nrow(narcotics_nn), round(0.75*nrow(narcotics_nn)))
train <- narcotics_nn[index,]
test <- narcotics_nn[-index,]
#train <- chicago_crime_nn_tr
train <- as.matrix(train)
#test <- chicago_crime_nn
test <- as.matrix(test)
#train_label<-target_train
#test_label<-target_test
train_label<-target_train[index]
test_label<-target_train[-index]
#main characteristics of the map
som_grid<-somgrid(xdim=8, ydim=8, topo="hexagonal")
#training the map
crime.som <- som(train, grid=som_grid,
rlen=100, alpha=c(0.05, 0.01),
radius= 2, keep.data=T)
# Names of the variables used
colnames(train)
[1] "primary_type" "description" "location_description" "arrest" "ward"
[6] "month"
# main characteristics of the map
summary(crime.som)
SOM of size 8x8 with a hexagonal topology and a bubble neighbourhood function.
The number of data layers is 1.
Distance measure(s) used: sumofsquares.
Training data included: 28136 objects.
Mean distance to the closest unit in the map: 27.532.
#Showing the training process
plot(crime.som, type="changes")

#node counts
plot(crime.som, type="counts", main="Examples per Neuron")

#Codes/Weight vectors
plot(crime.som, type="codes", main="Patterns Discovered")

#Scaling original data
set.seed(7)
#target_train.sc<-scale(chicago_crime_nn_tr)
#target_test.sc<-scale(chicago_crime_nn)
# creation of training and test datasets
#index <- sample(nrow(target_train.sc), round(0.75*nrow(crime.sc)))
#train <- target_train.sc
#test <- target_test.sc
#train <- chicago_crime_nn_tr
#test <- chicago_crime_nn
#index <- sample(nrow(chicago_crime_nn_tr), round(0.75*nrow(chicago_crime_nn_tr)))
#train <- chicago_crime_nn_tr[index,]
#test <- chicago_crime_nn_tr[-index,]
#train_label<-target_train
#test_label<-target_test
#main characteristics of the map
som_grid<-somgrid(xdim=8, ydim=8, topo="hexagonal")
set.seed(7)
kohmap <- xyf(train, train_label,
grid=som_grid,
rlen=100, alpha=c(0.05, 0.01),
radius= 2, keep.data=T)
#Showing the training process
plot(kohmap, type="changes")

#Showing distribution of wine labels in neurons
plot(kohmap, type="codes", codeRendering = "lines", shape="straight",
main=c("Crime"))


plot(kohmap, type="codes", codeRendering = "lines", shape="straight",
main=c(" patterns"))


# Plotting classes in neurons
#plot(kohmap, type="mapping", labels=as.numeric(train_label)+3,
# col=as.numeric(train_label)+3, pch=4, main="Map of classes", palette.name = terrain.colors)
#Prediction using the training data
print("TRAINING PREDICTION")
[1] "TRAINING PREDICTION"
kohmap.predict_tr<- predict(kohmap, newdata=train, whatmap = 1)
prediction_table_tr<-table(train_label,kohmap.predict_tr$predictions[[2]])
confusionMatrix(prediction_table_tr)
Confusion Matrix and Statistics
train_label 1 2 3 4 5 6 7 8 9 10 11 12 14 15 16 17 18 19 20 22 24 25 31
1 34 28 0 127 0 17 25 7 0 0 13 0 0 19 28 0 32 16 0 0 14 0 0
2 11 163 6 200 0 23 102 31 0 30 4 0 0 0 0 0 1 0 0 0 0 0 0
3 6 98 28 215 0 26 174 32 0 205 42 0 0 0 0 0 1 0 0 0 0 0 0
4 11 103 0 458 0 24 438 19 125 0 3 0 0 0 0 0 2 0 0 0 0 0 0
5 22 3 2 190 23 27 283 14 90 26 135 0 0 119 15 0 2 0 0 0 3 127 0
6 12 69 22 242 0 95 552 43 31 326 178 0 0 0 0 0 2 0 0 0 0 2 0
7 18 61 0 104 0 45 1282 51 183 139 231 0 0 0 0 0 0 0 0 0 0 1 0
8 3 0 0 5 0 9 527 55 216 179 147 0 0 0 0 0 0 0 0 0 0 4 0
9 12 28 8 33 0 23 477 24 306 115 81 0 0 0 0 0 0 0 0 0 0 0 0
10 3 0 11 3 0 10 69 55 35 1749 1059 0 0 3 0 0 1 0 0 0 0 5 0
11 1 66 4 98 2 1 85 54 0 1094 6437 0 0 120 47 0 2 2 0 0 9 52 0
12 24 55 0 102 0 16 41 10 0 55 321 0 0 7 2 0 2 0 0 0 1 7 0
14 1 19 0 28 5 4 22 5 0 17 79 0 0 15 2 0 0 2 0 0 0 30 0
15 0 0 1 0 6 0 16 4 0 186 1547 0 0 563 65 0 3 10 0 0 17 176 0
16 0 0 0 0 0 0 0 1 0 0 83 0 0 45 248 0 29 22 0 0 55 82 0
17 0 0 0 0 0 0 1 0 0 0 31 0 0 56 31 0 5 16 0 0 15 100 0
18 0 1 0 2 1 0 1 0 0 5 95 0 0 39 62 0 69 26 0 0 38 8 0
19 0 1 0 1 0 0 2 0 0 0 9 0 0 15 53 0 29 77 0 0 111 5 0
20 0 0 0 0 0 0 0 0 0 0 6 0 0 14 29 0 28 34 0 0 67 19 0
22 0 0 17 4 10 12 17 4 2 176 124 0 0 44 3 0 0 0 0 0 0 56 0
24 0 0 0 0 0 0 0 0 0 0 1 0 0 3 47 0 21 40 0 0 173 4 0
25 0 0 0 0 11 0 4 1 0 22 553 0 0 243 34 0 1 18 0 0 19 299 0
31 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Overall Statistics
Accuracy : 0.4286
95% CI : (0.4228, 0.4344)
No Information Rate : 0.3973
P-Value [Acc > NIR] : < 2.2e-16
Kappa : 0.3245
Mcnemar's Test P-Value : NA
Statistics by Class:
Class: 1 Class: 2 Class: 3 Class: 4 Class: 5 Class: 6 Class: 7 Class: 8 Class: 9 Class: 10 Class: 11 Class: 12
Sensitivity 0.215190 0.234532 0.2828283 0.25276 0.3965517 0.286145 0.31132 0.134146 0.30972 0.40449 0.5758 NA
Specificity 0.988348 0.985132 0.9715019 0.97246 0.9623193 0.946806 0.96532 0.960687 0.97050 0.94734 0.9035 0.97715
Pos Pred Value 0.094444 0.285464 0.0338573 0.38715 0.0212766 0.060356 0.60615 0.048035 0.27642 0.58242 0.7973 NA
Neg Pred Value 0.995536 0.980700 0.9974001 0.94976 0.9987063 0.991077 0.89101 0.986847 0.97477 0.89755 0.7636 NA
Prevalence 0.005616 0.024701 0.0035186 0.06440 0.0020614 0.011800 0.14636 0.014572 0.03512 0.15368 0.3973 0.00000
Detection Rate 0.001208 0.005793 0.0009952 0.01628 0.0008175 0.003376 0.04556 0.001955 0.01088 0.06216 0.2288 0.00000
Detection Prevalence 0.012795 0.020294 0.0293929 0.04205 0.0384205 0.055943 0.07517 0.040695 0.03934 0.10673 0.2870 0.02285
Balanced Accuracy 0.601769 0.609832 0.6271651 0.61261 0.6794355 0.616475 0.63832 0.547417 0.64011 0.67591 0.7396 NA
Class: 14 Class: 15 Class: 16 Class: 17 Class: 18 Class: 19 Class: 20 Class: 22 Class: 24 Class: 25 Class: 31
Sensitivity NA 0.43142 0.372372 NA 0.300000 0.292776 NA NA 0.331418 0.30604 NA
Specificity 0.991861 0.92430 0.988460 0.990937 0.990038 0.991892 0.992998 0.98333 0.995799 0.96664 1
Pos Pred Value NA 0.21704 0.438938 NA 0.198847 0.254125 NA NA 0.598616 0.24813 NA
Neg Pred Value NA 0.97095 0.984839 NA 0.994206 0.993317 NA NA 0.987467 0.97482 NA
Prevalence 0.000000 0.04638 0.023671 0.000000 0.008175 0.009347 0.000000 0.00000 0.018553 0.03472 0
Detection Rate 0.000000 0.02001 0.008814 0.000000 0.002452 0.002737 0.000000 0.00000 0.006149 0.01063 0
Detection Prevalence 0.008139 0.09220 0.020081 0.009063 0.012333 0.010769 0.007002 0.01667 0.010272 0.04283 0
Balanced Accuracy NA 0.67786 0.680416 NA 0.645019 0.642334 NA NA 0.663608 0.63634 NA
#Prediction using the test data
print("TEST PREDICTION")
[1] "TEST PREDICTION"
kohmap.predict<- predict(kohmap, newdata=test, whatmap = 1)
prediction_table<-table(test_label,kohmap.predict$predictions[[2]])
confusionMatrix(prediction_table)
Confusion Matrix and Statistics
test_label 1 2 3 4 5 6 7 8 9 10 11 12 14 15 16 17 18 19 20 22 24 25 31
1 11 6 0 49 0 1 3 1 0 0 1 0 0 2 8 0 10 4 0 0 3 0 0
2 4 53 0 76 0 11 28 9 0 9 2 0 0 0 0 0 0 0 0 0 0 0 0
3 2 42 7 66 0 5 65 13 0 75 17 0 0 0 0 0 0 0 0 0 0 0 0
4 4 42 0 145 0 6 140 6 37 0 1 0 0 0 0 0 0 0 0 0 0 1 0
5 1 1 0 65 6 6 120 3 38 10 44 0 0 36 2 0 0 0 0 0 2 43 0
6 3 23 10 70 0 26 178 16 20 109 65 0 0 0 0 0 0 0 0 0 0 0 0
7 1 10 1 37 0 13 406 17 65 33 95 0 0 0 0 0 0 0 0 0 0 0 0
8 1 0 0 1 0 1 145 11 74 57 51 0 0 0 0 0 0 0 0 0 0 2 0
9 5 8 4 14 0 13 169 8 131 31 22 0 0 0 0 0 0 0 0 0 0 0 0
10 1 0 6 0 0 6 20 13 13 576 359 0 0 1 0 0 1 0 0 0 0 0 0
11 0 21 1 28 1 0 27 25 0 368 2148 0 0 41 19 0 0 0 0 0 1 27 0
12 5 25 0 22 0 7 19 3 0 24 94 0 0 0 1 0 0 0 0 0 0 1 0
14 0 9 0 4 0 2 3 3 0 2 42 0 0 7 1 0 0 0 0 0 0 17 0
15 0 0 1 0 5 0 6 2 0 61 505 0 0 202 17 0 1 6 0 0 5 60 0
16 0 0 0 0 2 0 0 1 0 0 32 0 0 12 70 0 10 12 0 0 19 30 0
17 0 0 0 0 0 0 0 0 0 0 13 0 0 13 9 0 4 5 0 0 4 36 0
18 0 0 0 0 0 0 0 0 0 1 20 0 0 19 16 0 17 11 0 0 13 1 0
19 0 0 0 0 0 0 2 0 0 0 4 0 0 5 19 0 14 32 0 0 53 2 0
20 0 0 0 0 0 0 1 0 0 0 3 0 0 3 6 0 7 16 0 0 25 8 0
22 0 0 8 1 2 2 5 0 2 67 36 0 0 12 2 0 0 0 0 0 0 21 0
24 0 0 0 0 0 0 0 0 0 0 1 0 0 0 13 0 9 20 0 0 61 2 0
25 0 0 0 0 3 0 2 0 0 4 176 0 0 92 17 0 0 7 0 0 9 82 0
31 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Overall Statistics
Accuracy : 0.4248
95% CI : (0.4147, 0.4349)
No Information Rate : 0.3978
P-Value [Acc > NIR] : 5.519e-08
Kappa : 0.3199
Mcnemar's Test P-Value : NA
Statistics by Class:
Class: 1 Class: 2 Class: 3 Class: 4 Class: 5 Class: 6 Class: 7 Class: 8 Class: 9 Class: 10 Class: 11 Class: 12
Sensitivity 0.289474 0.220833 0.1842105 0.25087 0.3157895 0.262626 0.30321 0.083969 0.34474 0.40364 0.5757 NA
Specificity 0.990579 0.984790 0.9694893 0.97307 0.9603632 0.946767 0.96617 0.964100 0.96955 0.94718 0.9010 0.97857
Pos Pred Value 0.111111 0.276042 0.0239726 0.37958 0.0159151 0.050000 0.59882 0.032070 0.32346 0.57831 0.7935 NA
Neg Pred Value 0.997091 0.979645 0.9965885 0.95187 0.9985559 0.991760 0.89277 0.986720 0.97225 0.89849 0.7627 NA
Prevalence 0.004052 0.025589 0.0040516 0.06163 0.0020258 0.010555 0.14277 0.013967 0.04052 0.15215 0.3978 0.00000
Detection Rate 0.001173 0.005651 0.0007463 0.01546 0.0006397 0.002772 0.04329 0.001173 0.01397 0.06141 0.2290 0.00000
Detection Prevalence 0.010555 0.020471 0.0311334 0.04073 0.0401962 0.055443 0.07229 0.036571 0.04318 0.10619 0.2886 0.02143
Balanced Accuracy 0.640026 0.602812 0.5768499 0.61197 0.6380764 0.604697 0.63469 0.524035 0.65714 0.67541 0.7384 NA
Class: 14 Class: 15 Class: 16 Class: 17 Class: 18 Class: 19 Class: 20 Class: 22 Class: 24 Class: 25 Class: 31
Sensitivity NA 0.45393 0.350000 NA 0.232877 0.283186 NA NA 0.312821 0.246246 NA
Specificity 0.990404 0.92512 0.987145 0.991044 0.991296 0.989316 0.992643 0.98315 0.995100 0.965731 1
Pos Pred Value NA 0.23192 0.372340 NA 0.173469 0.244275 NA NA 0.575472 0.209184 NA
Neg Pred Value NA 0.97144 0.985856 NA 0.993966 0.991241 NA NA 0.985549 0.972071 NA
Prevalence 0.000000 0.04745 0.021324 0.000000 0.007783 0.012048 0.000000 0.00000 0.020791 0.035505 0
Detection Rate 0.000000 0.02154 0.007463 0.000000 0.001813 0.003412 0.000000 0.00000 0.006504 0.008743 0
Detection Prevalence 0.009596 0.09287 0.020045 0.008956 0.010449 0.013967 0.007357 0.01685 0.011302 0.041796 0
Balanced Accuracy NA 0.68953 0.668572 NA 0.612086 0.636251 NA NA 0.653960 0.605988 NA
## REDES
crimen <- subset(weapons_violation_tr, select=-c(case_number,block,day,latitude,longitude))
library(kohonen) # for building the SOM map
library(caret) #for confusion matrix
#Extracting target variable
target_train <- crimen$district
crimen <- subset(crimen, select=-c(district))
crimen$arrest <- as.factor(crimen$arrest)
crimen$arrest <- as.numeric(crimen$arrest)
crimen$primary_type <- as.factor(crimen$primary_type)
crimen$primary_type <- as.numeric(crimen$primary_type)
#narcotics_nn$district <- as.numeric(narcotics_nn$district)
#chicago_crime_nn$district <- as.factor(chicago_crime_nn$district)
crimen$description <- as.factor(crimen$description)
crimen$description <- as.numeric(crimen$description)
crimen$location_description <- as.factor(crimen$location_description)
crimen$location_description <- as.numeric(crimen$location_description)
crimen$month <- as.numeric(crimen$month)
#Scaling original data
set.seed(7)
#target_train.sc<-scale(chicago_crime_nn_tr)
#target_test.sc<-scale(chicago_crime_nn)
# creation of training and test datasets
index <- sample(nrow(crimen), round(0.75*nrow(crimen)))
train <- crimen[index,]
test <- crimen[-index,]
#train <- chicago_crime_nn_tr
train <- as.matrix(train)
#test <- chicago_crime_nn
test <- as.matrix(test)
#train_label<-target_train
#test_label<-target_test
train_label<-target_train[index]
test_label<-target_train[-index]
#main characteristics of the map
som_grid<-somgrid(xdim=12, ydim=12, topo="hexagonal")
#training the map
crime.som <- som(train, grid=som_grid,
rlen=100, alpha=c(0.05, 0.01),
radius= 2, keep.data=T)
# Names of the variables used
colnames(train)
[1] "primary_type" "description" "location_description" "arrest" "ward"
[6] "month"
# main characteristics of the map
summary(crime.som)
SOM of size 12x12 with a hexagonal topology and a bubble neighbourhood function.
The number of data layers is 1.
Distance measure(s) used: sumofsquares.
Training data included: 10154 objects.
Mean distance to the closest unit in the map: 7.334.
#Showing the training process
plot(crime.som, type="changes")

#node counts
plot(crime.som, type="counts", main="Examples per Neuron")

#Codes/Weight vectors
plot(crime.som, type="codes", main="Patterns Discovered")

#Scaling original data
set.seed(7)
#main characteristics of the map
som_grid<-somgrid(xdim=12, ydim=12, topo="hexagonal")
set.seed(7)
kohmap <- xyf(train, train_label,
grid=som_grid,
rlen=100, alpha=c(0.05, 0.01),
radius= 2, keep.data=T)
#Showing the training process
plot(kohmap, type="changes")

#Showing distribution of wine labels in neurons
plot(kohmap, type="codes", codeRendering = "lines", shape="straight",
main=c("Crime"))


plot(kohmap, type="codes", codeRendering = "lines", shape="straight",
main=c(" patterns"))


# Plotting classes in neurons
#plot(kohmap, type="mapping", labels=as.numeric(train_label)+3,
# col=as.numeric(train_label)+3, pch=4, main="Map of classes", palette.name = terrain.colors)
#Prediction using the training data
print("TRAINING PREDICTION")
[1] "TRAINING PREDICTION"
kohmap.predict_tr<- predict(kohmap, newdata=train, whatmap = 1)
prediction_table_tr<-table(train_label,kohmap.predict_tr$predictions[[2]])
confusionMatrix(prediction_table_tr)
Confusion Matrix and Statistics
train_label 1 2 3 4 5 6 7 8 9 10 11 12 14 15 16 17 18 19 20 22 24 25 31
1 7 28 8 7 3 4 0 0 0 1 1 4 1 0 2 1 1 5 0 0 0 0 0
2 4 141 66 26 1 38 10 0 0 3 0 0 1 0 0 0 0 0 0 0 0 0 0
3 1 48 178 103 7 152 27 0 0 7 0 0 0 0 0 0 0 0 0 0 0 0 0
4 0 29 34 496 104 55 9 0 22 0 0 0 0 0 0 0 0 0 0 0 0 0 0
5 0 3 2 262 462 15 12 0 11 0 0 0 0 7 0 3 1 0 0 0 0 43 0
6 0 23 81 166 30 285 303 0 2 44 2 0 0 0 0 0 0 0 0 0 0 0 0
7 0 28 51 55 1 100 883 25 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0
8 0 0 24 2 1 13 302 43 42 52 1 0 0 0 0 0 0 0 0 0 0 0 0
9 7 38 39 51 18 42 233 15 118 8 3 0 0 0 0 0 0 0 0 0 0 0 0
10 0 0 0 9 5 41 15 0 58 675 69 0 0 9 0 0 0 0 0 0 0 3 0
11 0 38 5 4 13 5 2 0 0 336 560 2 4 134 0 0 5 0 0 0 0 53 0
12 7 37 10 6 0 1 0 0 0 74 68 5 3 3 0 1 2 0 0 0 0 3 0
14 2 14 3 1 28 2 0 0 0 26 43 2 9 10 0 1 1 0 0 0 0 20 0
15 0 0 0 0 66 1 0 0 0 39 257 0 0 183 0 2 2 1 0 0 0 88 0
16 0 0 0 0 24 0 0 0 0 0 3 0 0 4 13 1 5 22 0 0 7 21 0
17 0 0 0 0 49 0 0 0 0 0 13 0 0 9 2 15 1 3 0 0 4 29 0
18 0 4 0 0 2 0 0 0 0 4 29 0 0 3 4 8 10 19 0 0 0 9 0
19 1 1 0 0 3 0 0 0 0 0 5 0 0 0 1 0 3 45 0 0 32 2 0
20 0 0 0 0 8 0 0 0 0 0 0 0 0 2 5 3 2 14 0 0 32 9 0
22 0 0 26 10 104 90 20 0 1 30 4 0 0 7 0 2 0 0 0 0 0 14 0
24 0 0 0 0 3 0 0 0 0 0 1 0 0 2 3 2 1 11 0 0 106 10 0
25 0 2 0 0 120 1 0 0 0 10 156 0 0 83 0 4 0 1 0 0 0 190 0
31 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Overall Statistics
Accuracy : 0.4357
95% CI : (0.426, 0.4454)
No Information Rate : 0.1788
P-Value [Acc > NIR] : < 2.2e-16
Kappa : 0.3855
Mcnemar's Test P-Value : NA
Statistics by Class:
Class: 1 Class: 2 Class: 3 Class: 4 Class: 5 Class: 6 Class: 7 Class: 8 Class: 9 Class: 10 Class: 11 Class: 12
Sensitivity 0.2413793 0.32488 0.33776 0.41402 0.43916 0.33728 0.48623 0.518072 0.46457 0.51487 0.46091 0.3846154
Specificity 0.9934815 0.98467 0.96416 0.97175 0.96056 0.93007 0.96858 0.956608 0.95414 0.97637 0.93277 0.9787989
Pos Pred Value 0.0958904 0.48621 0.34034 0.66222 0.56273 0.30449 0.77118 0.089583 0.20629 0.76357 0.48234 0.0227273
Neg Pred Value 0.9978177 0.97030 0.96376 0.92536 0.93678 0.93925 0.89644 0.995865 0.98581 0.93139 0.92717 0.9991947
Prevalence 0.0028560 0.04274 0.05190 0.11798 0.10360 0.08322 0.17885 0.008174 0.02501 0.12911 0.11966 0.0012803
Detection Rate 0.0006894 0.01389 0.01753 0.04885 0.04550 0.02807 0.08696 0.004235 0.01162 0.06648 0.05515 0.0004924
Detection Prevalence 0.0071893 0.02856 0.05151 0.07376 0.08085 0.09218 0.11276 0.047272 0.05633 0.08706 0.11434 0.0216663
Balanced Accuracy 0.6174304 0.65478 0.65096 0.69289 0.69986 0.63367 0.72741 0.737340 0.70935 0.74562 0.69684 0.6817072
Class: 14 Class: 15 Class: 16 Class: 17 Class: 18 Class: 19 Class: 20 Class: 22 Class: 24 Class: 25 Class: 31
Sensitivity 0.5000000 0.40132 0.433333 0.348837 0.2941176 0.371901 NA NA 0.58564 0.38462 NA
Specificity 0.9849053 0.95298 0.991407 0.989121 0.9918972 0.995216 0.992614 0.96967 0.99669 0.96097 1
Pos Pred Value 0.0555556 0.28638 0.130000 0.120000 0.1086957 0.483871 NA NA 0.76259 0.33510 NA
Neg Pred Value 0.9990993 0.97131 0.998309 0.997208 0.9976148 0.992446 NA NA 0.99251 0.96829 NA
Prevalence 0.0017727 0.04491 0.002955 0.004235 0.0033484 0.011916 0.000000 0.00000 0.01783 0.04865 0
Detection Rate 0.0008864 0.01802 0.001280 0.001477 0.0009848 0.004432 0.000000 0.00000 0.01044 0.01871 0
Detection Prevalence 0.0159543 0.06293 0.009848 0.012310 0.0090605 0.009159 0.007386 0.03033 0.01369 0.05584 0
Balanced Accuracy 0.7424526 0.67715 0.712370 0.668979 0.6430074 0.683558 NA NA 0.79116 0.67279 NA
#Prediction using the test data
print("TEST PREDICTION")
[1] "TEST PREDICTION"
kohmap.predict<- predict(kohmap, newdata=test, whatmap = 1)
prediction_table<-table(test_label,kohmap.predict$predictions[[2]])
confusionMatrix(prediction_table)
Confusion Matrix and Statistics
test_label 1 2 3 4 5 6 7 8 9 10 11 12 14 15 16 17 18 19 20 22 24 25 31
1 2 14 1 4 0 0 0 0 0 0 1 0 1 0 0 3 0 5 0 0 0 2 0
2 1 38 19 9 1 14 4 0 0 1 0 1 3 0 0 0 0 0 0 0 0 0 0
3 0 19 46 25 4 47 13 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
4 0 12 7 174 35 23 8 0 7 0 0 0 0 0 0 0 0 0 0 0 0 0 0
5 0 1 2 89 131 11 3 0 6 0 2 0 0 2 0 1 0 0 0 0 0 16 0
6 0 8 31 61 9 103 102 0 1 18 0 0 0 0 0 0 0 0 0 0 0 0 0
7 0 13 20 27 1 43 324 11 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
8 0 0 12 0 2 3 98 20 18 14 0 0 0 0 0 0 0 0 0 0 0 0 0
9 4 18 12 14 12 14 65 3 26 1 2 0 0 0 0 0 0 0 0 0 0 0 0
10 0 0 0 2 4 20 7 0 17 188 32 0 0 5 0 0 0 0 0 0 0 0 0
11 1 8 3 0 5 7 1 0 0 106 179 0 1 48 0 1 1 0 0 0 0 13 0
12 5 14 3 3 0 1 0 0 0 22 21 1 2 1 0 0 1 0 0 0 0 3 0
14 0 9 3 0 6 1 0 0 0 8 19 2 1 0 0 1 0 0 0 0 0 4 0
15 0 0 0 0 16 1 0 0 0 15 84 0 0 55 0 1 0 1 0 0 0 32 0
16 0 0 0 0 6 0 0 0 0 0 2 0 0 3 4 1 1 7 0 0 2 6 0
17 0 0 0 0 22 0 0 0 0 0 3 0 0 4 1 3 0 1 0 0 0 16 0
18 0 1 0 0 0 0 0 0 0 0 10 0 0 0 1 4 5 6 0 0 0 3 0
19 0 1 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 14 0 0 12 1 0
20 0 0 0 0 3 0 0 0 0 0 0 0 0 1 3 3 0 3 0 0 7 1 0
22 0 0 7 2 30 28 4 0 1 17 0 0 0 1 0 0 0 0 0 0 0 3 0
24 0 0 0 0 2 0 0 0 0 0 0 0 0 1 2 0 1 7 0 0 21 4 0
25 0 0 0 0 33 0 0 0 0 4 39 0 0 38 0 0 0 0 0 0 0 73 0
31 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Overall Statistics
Accuracy : 0.4161
95% CI : (0.3994, 0.4329)
No Information Rate : 0.1859
P-Value [Acc > NIR] : < 2.2e-16
Kappa : 0.3626
Mcnemar's Test P-Value : NA
Statistics by Class:
Class: 1 Class: 2 Class: 3 Class: 4 Class: 5 Class: 6 Class: 7 Class: 8 Class: 9 Class: 10 Class: 11 Class: 12
Sensitivity 0.153846 0.24359 0.27711 0.42439 0.40432 0.32595 0.51510 0.58824 0.342105 0.47716 0.4543 0.2500000
Specificity 0.990804 0.98358 0.96644 0.96907 0.95654 0.92503 0.95826 0.95612 0.956167 0.97090 0.9348 0.9775148
Pos Pred Value 0.060606 0.41758 0.29870 0.65414 0.49621 0.30931 0.73804 0.11976 0.152047 0.68364 0.4786 0.0129870
Neg Pred Value 0.996717 0.96417 0.96285 0.92431 0.93814 0.93019 0.89643 0.99565 0.984438 0.93374 0.9286 0.9990928
Prevalence 0.003842 0.04610 0.04905 0.12116 0.09574 0.09338 0.18587 0.01005 0.022459 0.11643 0.1164 0.0011820
Detection Rate 0.000591 0.01123 0.01359 0.05142 0.03871 0.03044 0.09574 0.00591 0.007683 0.05556 0.0529 0.0002955
Detection Prevalence 0.009752 0.02689 0.04551 0.07861 0.07801 0.09840 0.12973 0.04935 0.050532 0.08126 0.1105 0.0227541
Balanced Accuracy 0.572325 0.61359 0.62177 0.69673 0.68043 0.62549 0.73668 0.77218 0.649136 0.72403 0.6945 0.6137574
Class: 14 Class: 15 Class: 16 Class: 17 Class: 18 Class: 19 Class: 20 Class: 22 Class: 24 Class: 25 Class: 31
Sensitivity 0.1250000 0.34591 0.363636 0.1666667 0.555556 0.318182 NA NA 0.500000 0.41243 NA
Specificity 0.9843009 0.95349 0.991699 0.9860368 0.992593 0.995210 0.993794 0.97252 0.994913 0.96445 1
Pos Pred Value 0.0185185 0.26829 0.125000 0.0600000 0.166667 0.466667 NA NA 0.552632 0.39037 NA
Neg Pred Value 0.9978979 0.96729 0.997912 0.9955009 0.998807 0.991055 NA NA 0.993724 0.96747 NA
Prevalence 0.0023641 0.04699 0.003251 0.0053191 0.002660 0.013002 0.000000 0.00000 0.012411 0.05230 0
Detection Rate 0.0002955 0.01625 0.001182 0.0008865 0.001478 0.004137 0.000000 0.00000 0.006206 0.02157 0
Detection Prevalence 0.0159574 0.06058 0.009456 0.0147754 0.008865 0.008865 0.006206 0.02748 0.011229 0.05526 0
Balanced Accuracy 0.5546505 0.64970 0.677668 0.5763518 0.774074 0.656696 NA NA 0.747457 0.68844 NA
library(RColorBrewer)
groups<-23
#Applying hierarchical clustering for grouping patterns
crime.hc=cutree(hclust(dist(crime.som$codes[[1]])), groups)
plot(crime.som, type="codes", bgcol = heat.colors(groups)[crime.hc],
main="clustering the patterns discovered")
add.cluster.boundaries(crime.som,crime.hc)

LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKIyMgUkVBRCBUSEUgREFUQQoKYGBge3J9CmxpYnJhcnkoZHBseXIpCmxpYnJhcnkoZGF0YS50YWJsZSkKbGlicmFyeShtbHRvb2xzKQpjaGljYWdvX2NyaW1lIDwtIHJlYWQudGFibGUoZmlsZSA9ICJjaGljYWdvX2NyaW1lX2NsZWFuLmNzdiIsICNOYW1lIG9mIHRleHQgZmlsZS4KICAgICAgICAgICAgICAgICAgICAgIHNlcCA9ICIsIiwgICAgICAgICAgICAgICAgICAgICAgICNTZXBhcmF0aW9uIGNoYXJhY3Rlci4KICAgICAgICAgICAgICAgICAgICAgIGhlYWRlciA9IFRSVUUsICAgICAgICAgICAgICAgICAgICNJZiBjb2x1bW4gbmFtZXMgYXJlIGluIHRoZSBmaXJzdCByb3cuCiAgICAgICAgICAgICAgICAgICAgICBuYS5zdHJpbmdzID0gIk5BIiwgICAgICAgICAgICAgICAjQ2hhcmFjdGVyIHRvIGJlIG1hcmtlZCBhcyBtaXNzaW5nIHZhbHVlLgogICAgICAgICAgICAgICAgICAgICAgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFKQoKY2hpY2Fnb19jcmltZSRsb2NhdGlvbl9kZXNjcmlwdGlvbiA8LSAoZ3N1YigiLCIsIiAiLGNoaWNhZ29fY3JpbWUkbG9jYXRpb25fZGVzY3JpcHRpb24pKQpjaGljYWdvX2NyaW1lJGRlc2NyaXB0aW9uIDwtIGdzdWIoIjo9IiwiIixjaGljYWdvX2NyaW1lJGRlc2NyaXB0aW9uKQpjaGljYWdvX2NyaW1lJGRlc2NyaXB0aW9uIDwtIGdzdWIoIjoiLCIiLGNoaWNhZ29fY3JpbWUkZGVzY3JpcHRpb24pCmNoaWNhZ29fY3JpbWUkZGVzY3JpcHRpb24gPC0gZ3N1YigiTUFOVS9QT1NTLiBXLyIsIiIsY2hpY2Fnb19jcmltZSRkZXNjcmlwdGlvbikKY2hpY2Fnb19jcmltZSRkZXNjcmlwdGlvbiA8LSBnc3ViKCIsIiwiIixjaGljYWdvX2NyaW1lJGRlc2NyaXB0aW9uKQojY2hpY2Fnb19jcmltZSRkZXNjcmlwdGlvbiA8LSBnc3ViKCIuIiwiIixjaGljYWdvX2NyaW1lJGRlc2NyaXB0aW9uKQpjaGljYWdvX2NyaW1lJGxvY2F0aW9uX2Rlc2NyaXB0aW9uIDwtIGdzdWIoIihFLkcuICBVQkVSICBMWUZUKSIsIiIsY2hpY2Fnb19jcmltZSRsb2NhdGlvbl9kZXNjcmlwdGlvbikKY2hpY2Fnb19jcmltZSRsb2NhdGlvbl9kZXNjcmlwdGlvbiA8LSBnc3ViKCIsIiwiIixjaGljYWdvX2NyaW1lJGxvY2F0aW9uX2Rlc2NyaXB0aW9uKQojY2hpY2Fnb19jcmltZSRsb2NhdGlvbl9kZXNjcmlwdGlvbiA8LSBnc3ViKCIuIiwiIixjaGljYWdvX2NyaW1lJGxvY2F0aW9uX2Rlc2NyaXB0aW9uKQoKY2hpY2Fnb19jcmltZSA8LSBjaGljYWdvX2NyaW1lICU+JQogICAgZHBseXI6Om11dGF0ZSh5ZWFyID0gbHVicmlkYXRlOjp5ZWFyKGRhdGUpLCAKICAgICAgICAgICAgICAgIG1vbnRoID0gbHVicmlkYXRlOjptb250aChkYXRlKSwgCiAgICAgICAgICAgICAgICBkYXkgPSBsdWJyaWRhdGU6OmRheShkYXRlKSkKY2hpY2Fnb19jcmltZSA8LSBuYS5vbWl0KGNoaWNhZ29fY3JpbWUpCmNoaWNhZ29fY3JpbWUgPC0gc2VsZWN0KGNoaWNhZ29fY3JpbWUsLWMoWCx1bmlxdWVfa2V5LCB4X2Nvb3JkaW5hdGUsIHlfY29vcmRpbmF0ZSwgbG9jYXRpb24sIGRvbWVzdGljLCBmYmlfY29kZSwgZGF0ZSx5ZWFyKSkKY2hpY2Fnb19jcmltZSRkaXN0cmljdCA8LSBmYWN0b3IoY2hpY2Fnb19jcmltZSRkaXN0cmljdCkKCnVuaXF1ZShjaGljYWdvX2NyaW1lJHByaW1hcnlfdHlwZSkKCmhlYWQoY2hpY2Fnb19jcmltZSkKc3VtbWFyeShjaGljYWdvX2NyaW1lKQpgYGAKCiMjIFJlYWQgdGhlIHRyYWluaW5nIHNldAoKYGBge3J9CmxpYnJhcnkoZHBseXIpCmxpYnJhcnkoZGF0YS50YWJsZSkKbGlicmFyeShtbHRvb2xzKQpjaGljYWdvX2NyaW1lX3RyIDwtIHJlYWQudGFibGUoZmlsZSA9ICJjaGljYWdvX2NyaW1lX3RyLmNzdiIsICNOYW1lIG9mIHRleHQgZmlsZS4KICAgICAgICAgICAgICAgICAgICAgIHNlcCA9ICIsIiwgICAgICAgICAgICAgICAgICAgICAgICNTZXBhcmF0aW9uIGNoYXJhY3Rlci4KICAgICAgICAgICAgICAgICAgICAgIGhlYWRlciA9IFRSVUUsICAgICAgICAgICAgICAgICAgICNJZiBjb2x1bW4gbmFtZXMgYXJlIGluIHRoZSBmaXJzdCByb3cuCiAgICAgICAgICAgICAgICAgICAgICBuYS5zdHJpbmdzID0gIk5BIiwgICAgICAgICAgICAgICAjQ2hhcmFjdGVyIHRvIGJlIG1hcmtlZCBhcyBtaXNzaW5nIHZhbHVlLgogICAgICAgICAgICAgICAgICAgICAgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFKQoKY2hpY2Fnb19jcmltZV90ciRsb2NhdGlvbl9kZXNjcmlwdGlvbiA8LSAoZ3N1YigiLCIsIiAiLGNoaWNhZ29fY3JpbWVfdHIkbG9jYXRpb25fZGVzY3JpcHRpb24pKQpjaGljYWdvX2NyaW1lX3RyJGRlc2NyaXB0aW9uIDwtIGdzdWIoIjo9IiwiIixjaGljYWdvX2NyaW1lX3RyJGRlc2NyaXB0aW9uKQpjaGljYWdvX2NyaW1lX3RyJGRlc2NyaXB0aW9uIDwtIGdzdWIoIjoiLCIiLGNoaWNhZ29fY3JpbWVfdHIkZGVzY3JpcHRpb24pCmNoaWNhZ29fY3JpbWVfdHIkZGVzY3JpcHRpb24gPC0gZ3N1YigiTUFOVS9QT1NTLiBXLyIsIiIsY2hpY2Fnb19jcmltZV90ciRkZXNjcmlwdGlvbikKY2hpY2Fnb19jcmltZV90ciRkZXNjcmlwdGlvbiA8LSBnc3ViKCIsIiwiIixjaGljYWdvX2NyaW1lX3RyJGRlc2NyaXB0aW9uKQojY2hpY2Fnb19jcmltZSRkZXNjcmlwdGlvbiA8LSBnc3ViKCIuIiwiIixjaGljYWdvX2NyaW1lJGRlc2NyaXB0aW9uKQpjaGljYWdvX2NyaW1lX3RyJGxvY2F0aW9uX2Rlc2NyaXB0aW9uIDwtIGdzdWIoIihFLkcuICBVQkVSICBMWUZUKSIsIiIsY2hpY2Fnb19jcmltZV90ciRsb2NhdGlvbl9kZXNjcmlwdGlvbikKY2hpY2Fnb19jcmltZV90ciRsb2NhdGlvbl9kZXNjcmlwdGlvbiA8LSBnc3ViKCIsIiwiIixjaGljYWdvX2NyaW1lX3RyJGxvY2F0aW9uX2Rlc2NyaXB0aW9uKQojY2hpY2Fnb19jcmltZSRsb2NhdGlvbl9kZXNjcmlwdGlvbiA8LSBnc3ViKCIuIiwiIixjaGljYWdvX2NyaW1lJGxvY2F0aW9uX2Rlc2NyaXB0aW9uKQoKY2hpY2Fnb19jcmltZV90ciA8LSBjaGljYWdvX2NyaW1lX3RyICU+JQogICAgZHBseXI6Om11dGF0ZSh5ZWFyID0gbHVicmlkYXRlOjp5ZWFyKGRhdGUpLCAKICAgICAgICAgICAgICAgIG1vbnRoID0gbHVicmlkYXRlOjptb250aChkYXRlKSwgCiAgICAgICAgICAgICAgICBkYXkgPSBsdWJyaWRhdGU6OmRheShkYXRlKSkKCmNoaWNhZ29fY3JpbWVfdHIgPC0gc2VsZWN0KGNoaWNhZ29fY3JpbWVfdHIsLWMoWCx1bmlxdWVfa2V5LCB4X2Nvb3JkaW5hdGUsIHlfY29vcmRpbmF0ZSwgbG9jYXRpb24sIGRvbWVzdGljLCBmYmlfY29kZSwgZGF0ZSx5ZWFyKSkKCmNoaWNhZ29fY3JpbWVfdHIgPC0gbmEub21pdChjaGljYWdvX2NyaW1lX3RyKQpjaGljYWdvX2NyaW1lX3RyJGRpc3RyaWN0IDwtIGZhY3RvcihjaGljYWdvX2NyaW1lX3RyJGRpc3RyaWN0KQoKdW5pcXVlKGNoaWNhZ29fY3JpbWVfdHIkcHJpbWFyeV90eXBlKQoKaGVhZChjaGljYWdvX2NyaW1lX3RyKQpzdW1tYXJ5KGNoaWNhZ29fY3JpbWVfdHIpCgpjaGljYWdvX2NyaW1lX3RyJHByaW1hcnlfdHlwZVtjaGljYWdvX2NyaW1lX3RyJHByaW1hcnlfdHlwZSA9PSAiQ1JJTUlOQUwgVFJFU1BBU1MiXSA8LSAiUk9CQkVSWSIKY2hpY2Fnb19jcmltZV90ciRwcmltYXJ5X3R5cGVbY2hpY2Fnb19jcmltZV90ciRwcmltYXJ5X3R5cGUgPT0gIkJVUkdMQVJZIl0gPC0gIlJPQkJFUlkiCmNoaWNhZ29fY3JpbWVfdHIkcHJpbWFyeV90eXBlW2NoaWNhZ29fY3JpbWVfdHIkcHJpbWFyeV90eXBlID09ICJNT1RPUiBWRUhJQ0xFIFRIRUZUIl0gPC0gIlRIRUZUIgpjaGljYWdvX2NyaW1lX3RyJHByaW1hcnlfdHlwZVtjaGljYWdvX2NyaW1lX3RyJHByaW1hcnlfdHlwZSA9PSAiSE9NSUNJREUiXSA8LSAiVklPTEVOVCBDUklNRSIKY2hpY2Fnb19jcmltZV90ciRwcmltYXJ5X3R5cGVbY2hpY2Fnb19jcmltZV90ciRwcmltYXJ5X3R5cGUgPT0gIktJRE5BUFBJTkciXSA8LSAiVklPTEVOVCBDUklNRSIKY2hpY2Fnb19jcmltZV90ciRwcmltYXJ5X3R5cGVbY2hpY2Fnb19jcmltZV90ciRwcmltYXJ5X3R5cGUgPT0gIkJBVFRFUlkiXSA8LSAiVklPTEVOVCBDUklNRSIKY2hpY2Fnb19jcmltZV90ciRwcmltYXJ5X3R5cGVbY2hpY2Fnb19jcmltZV90ciRwcmltYXJ5X3R5cGUgPT0gIklOVElNSURBVElPTiJdIDwtICJWSU9MRU5UIENSSU1FIgpjaGljYWdvX2NyaW1lX3RyJHByaW1hcnlfdHlwZVtjaGljYWdvX2NyaW1lX3RyJHByaW1hcnlfdHlwZSA9PSAiQVJTT04iXSA8LSAiVklPTEVOVCBDUklNRSIKY2hpY2Fnb19jcmltZV90ciRwcmltYXJ5X3R5cGVbY2hpY2Fnb19jcmltZV90ciRwcmltYXJ5X3R5cGUgPT0gIlBST1NUSVRVVElPTiJdIDwtICJTRVggT0ZGRU5TRSIKY2hpY2Fnb19jcmltZV90ciRwcmltYXJ5X3R5cGVbY2hpY2Fnb19jcmltZV90ciRwcmltYXJ5X3R5cGUgPT0gIkNSSU0gU0VYVUFMIEFTU0FVTFQiXSA8LSAiU0VYIE9GRkVOU0UiCmNoaWNhZ29fY3JpbWVfdHIkcHJpbWFyeV90eXBlW2NoaWNhZ29fY3JpbWVfdHIkcHJpbWFyeV90eXBlID09ICJPVEhFUiBOQVJDT1RJQyBWSU9MQVRJT04iXSA8LSAiTkFSQ09USUNTIgpjaGljYWdvX2NyaW1lX3RyJHByaW1hcnlfdHlwZSA8LSBmYWN0b3IoY2hpY2Fnb19jcmltZV90ciRwcmltYXJ5X3R5cGUpCgpjaGljYWdvX2NyaW1lX3N1YnNldF90ciA8LSBzdWJzZXQoY2hpY2Fnb19jcmltZV90ciwgcHJpbWFyeV90eXBlPT0iQVNTQVVMVCIgfCBwcmltYXJ5X3R5cGUgPT0gIlZJT0xFTlQgQ1JJTUUiIHwgcHJpbWFyeV90eXBlID09ICJUSEVGVCIgfCBwcmltYXJ5X3R5cGU9PSJOQVJDT1RJQ1MiIHwgcHJpbWFyeV90eXBlID09ICJXRUFQT05TIFZJT0xBVElPTiIgfCBwcmltYXJ5X3R5cGU9PSJST0JCRVJZIiB8IHByaW1hcnlfdHlwZSA9PSAiQ1JJTUlOQUwgREFNQUdFIiB8IHByaW1hcnlfdHlwZSA9PSAiREVDRVBUSVZFIFBSQUNUSUNFIiApCgpjaGljYWdvX2NyaW1lX3N1YnNldF90ciRwcmltYXJ5X3R5cGUgPC0gZmFjdG9yKGNoaWNhZ29fY3JpbWVfc3Vic2V0X3RyJHByaW1hcnlfdHlwZSkKY2hpY2Fnb19jcmltZV9zdWJzZXRfdHIgPC0gbmEub21pdChjaGljYWdvX2NyaW1lX3N1YnNldF90cikKbGlicmFyeShEYXRhRXhwbG9yZXIpCnBsb3Rfc3RyKGNoaWNhZ29fY3JpbWVfc3Vic2V0X3RyKQpwbG90X21pc3NpbmcoY2hpY2Fnb19jcmltZV9zdWJzZXRfdHIpCiNwbG90X2hpc3RvZ3JhbShjaGljYWdvX2NyaW1lX3N1YnNldCkKI3Bsb3RfZGVuc2l0eShjaGljYWdvX2NyaW1lX3N1YnNldCkKI3Bsb3RfY29ycmVsYXRpb24oY2hpY2Fnb19udW1lcmljLCB0eXBlID0gJ2NvbnRpbnVvdXMnKQpjaGljYWdvX2NyaW1lX3N1YnNldF90ciRtb250aCA8LSBhcy5mYWN0b3IoY2hpY2Fnb19jcmltZV9zdWJzZXRfdHIkbW9udGgpCgpwbG90X2JhcihjaGljYWdvX2NyaW1lX3N1YnNldF90cikKYGBgCiMjIEVYUExPUkFUT1JZIEFOQUxZU0lTCgpgYGB7cn0KbGlicmFyeSh0aWR5dmVyc2UpCgpnZ3Bsb3QoZGF0YSA9IGNoaWNhZ29fY3JpbWUpICsKICBnZW9tX2JhcihtYXBwaW5nID0gYWVzKHggPSBwcmltYXJ5X3R5cGUpKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCwgaGp1c3QgPSAxKSkKCmNoaWNhZ29fY3JpbWUgJT4lIAogIGNvdW50KHByaW1hcnlfdHlwZSkKCmdncGxvdChkYXRhID0gY2hpY2Fnb19jcmltZSkgKwogIGdlb21fYmFyKG1hcHBpbmcgPSBhZXMoeCA9IGRpc3RyaWN0KSkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMSkpCgpjaGljYWdvX2NyaW1lICU+JSAKICBjb3VudChkaXN0cmljdCkKCmdncGxvdChkYXRhID0gY2hpY2Fnb19jcmltZSkgKwogIGdlb21fYmFyKG1hcHBpbmcgPSBhZXMoeCA9IGFycmVzdCkpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDEpKQoKY2hpY2Fnb19jcmltZSAlPiUgCiAgY291bnQoYXJyZXN0KQoKI2NoaWNhZ29fY3JpbWUkcHJpbWFyeV90eXBlIDwtIGFzLmNoYXJhY3RlcihqdW5rJG5tKQpjaGljYWdvX2NyaW1lJHByaW1hcnlfdHlwZVtjaGljYWdvX2NyaW1lJHByaW1hcnlfdHlwZSA9PSAiQ1JJTUlOQUwgVFJFU1BBU1MiXSA8LSAiUk9CQkVSWSIKY2hpY2Fnb19jcmltZSRwcmltYXJ5X3R5cGVbY2hpY2Fnb19jcmltZSRwcmltYXJ5X3R5cGUgPT0gIkJVUkdMQVJZIl0gPC0gIlJPQkJFUlkiCmNoaWNhZ29fY3JpbWUkcHJpbWFyeV90eXBlW2NoaWNhZ29fY3JpbWUkcHJpbWFyeV90eXBlID09ICJNT1RPUiBWRUhJQ0xFIFRIRUZUIl0gPC0gIlRIRUZUIgpjaGljYWdvX2NyaW1lJHByaW1hcnlfdHlwZVtjaGljYWdvX2NyaW1lJHByaW1hcnlfdHlwZSA9PSAiSE9NSUNJREUiXSA8LSAiVklPTEVOVCBDUklNRSIKY2hpY2Fnb19jcmltZSRwcmltYXJ5X3R5cGVbY2hpY2Fnb19jcmltZSRwcmltYXJ5X3R5cGUgPT0gIktJRE5BUFBJTkciXSA8LSAiVklPTEVOVCBDUklNRSIKY2hpY2Fnb19jcmltZSRwcmltYXJ5X3R5cGVbY2hpY2Fnb19jcmltZSRwcmltYXJ5X3R5cGUgPT0gIkJBVFRFUlkiXSA8LSAiVklPTEVOVCBDUklNRSIKY2hpY2Fnb19jcmltZSRwcmltYXJ5X3R5cGVbY2hpY2Fnb19jcmltZSRwcmltYXJ5X3R5cGUgPT0gIklOVElNSURBVElPTiJdIDwtICJWSU9MRU5UIENSSU1FIgpjaGljYWdvX2NyaW1lJHByaW1hcnlfdHlwZVtjaGljYWdvX2NyaW1lJHByaW1hcnlfdHlwZSA9PSAiQVJTT04iXSA8LSAiVklPTEVOVCBDUklNRSIKY2hpY2Fnb19jcmltZSRwcmltYXJ5X3R5cGVbY2hpY2Fnb19jcmltZSRwcmltYXJ5X3R5cGUgPT0gIlBST1NUSVRVVElPTiJdIDwtICJTRVggT0ZGRU5TRSIKY2hpY2Fnb19jcmltZSRwcmltYXJ5X3R5cGVbY2hpY2Fnb19jcmltZSRwcmltYXJ5X3R5cGUgPT0gIkNSSU0gU0VYVUFMIEFTU0FVTFQiXSA8LSAiU0VYIE9GRkVOU0UiCmNoaWNhZ29fY3JpbWUkcHJpbWFyeV90eXBlW2NoaWNhZ29fY3JpbWUkcHJpbWFyeV90eXBlID09ICJPVEhFUiBOQVJDT1RJQyBWSU9MQVRJT04iXSA8LSAiTkFSQ09USUNTIgpjaGljYWdvX2NyaW1lJHByaW1hcnlfdHlwZSA8LSBmYWN0b3IoY2hpY2Fnb19jcmltZSRwcmltYXJ5X3R5cGUpCgpnZ3Bsb3QoZGF0YSA9IGNoaWNhZ29fY3JpbWUpICsKICBnZW9tX2JhcihtYXBwaW5nID0gYWVzKHggPSBwcmltYXJ5X3R5cGUpKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCwgaGp1c3QgPSAxKSkKCmNoaWNhZ29fY3JpbWUgJT4lIAogIGNvdW50KHByaW1hcnlfdHlwZSkKCmNoaWNhZ29fY3JpbWVfc3Vic2V0IDwtIHN1YnNldChjaGljYWdvX2NyaW1lLCBwcmltYXJ5X3R5cGU9PSJBU1NBVUxUIiB8IHByaW1hcnlfdHlwZSA9PSAiVklPTEVOVCBDUklNRSIgfCBwcmltYXJ5X3R5cGUgPT0gIlRIRUZUIiB8IHByaW1hcnlfdHlwZT09Ik5BUkNPVElDUyIgfCBwcmltYXJ5X3R5cGUgPT0gIldFQVBPTlMgVklPTEFUSU9OIiB8IHByaW1hcnlfdHlwZT09IlJPQkJFUlkiIHwgcHJpbWFyeV90eXBlID09ICJDUklNSU5BTCBEQU1BR0UiIHwgcHJpbWFyeV90eXBlID09ICJERUNFUFRJVkUgUFJBQ1RJQ0UiICkKY2hpY2Fnb19jcmltZV9zdWJzZXQkcHJpbWFyeV90eXBlIDwtIGZhY3RvcihjaGljYWdvX2NyaW1lX3N1YnNldCRwcmltYXJ5X3R5cGUpCmdncGxvdChkYXRhID0gY2hpY2Fnb19jcmltZV9zdWJzZXQpICsKICBnZW9tX2JhcihtYXBwaW5nID0gYWVzKHggPSBwcmltYXJ5X3R5cGUpKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCwgaGp1c3QgPSAxKSkKCmdncGxvdChkYXRhID0gY2hpY2Fnb19jcmltZV9zdWJzZXQpICsKICBnZW9tX2NvdW50KG1hcHBpbmcgPSBhZXMoeCA9IHByaW1hcnlfdHlwZSwgeSA9IGRpc3RyaWN0KSkgKyAKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCBoanVzdCA9IDEpKQoKZ2dwbG90KGRhdGEgPSBjaGljYWdvX2NyaW1lX3N1YnNldCkgKwogIGdlb21fY291bnQobWFwcGluZyA9IGFlcyh4ID0gYXJyZXN0LCB5ID0gcHJpbWFyeV90eXBlKSkgKyAKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCBoanVzdCA9IDEpKQoKZ2dwbG90KGRhdGEgPSBjaGljYWdvX2NyaW1lX3N1YnNldCkgKwogIGdlb21fY291bnQobWFwcGluZyA9IGFlcyh4ID0gYXJyZXN0LCB5ID0gZGlzdHJpY3QpKSArIAogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIGhqdXN0ID0gMSkpCgpgYGAKCiMjIEVYUExPUkFUT1JZIEFOQUxZU0lTIEJZIENSSU1FCgpgYGB7cn0KYXNzYXVsdCA8LSBzdWJzZXQoY2hpY2Fnb19jcmltZV9zdWJzZXQsIHByaW1hcnlfdHlwZT09IkFTU0FVTFQiKQp2aW9sZW50X2NyaW1lIDwtIHN1YnNldChjaGljYWdvX2NyaW1lX3N1YnNldCwgcHJpbWFyeV90eXBlPT0iVklPTEVOVCBDUklNRSIpCnRoZWZ0IDwtIHN1YnNldChjaGljYWdvX2NyaW1lX3N1YnNldCwgcHJpbWFyeV90eXBlPT0iVEhFRlQiKQpuYXJjb3RpY3MgPC0gc3Vic2V0KGNoaWNhZ29fY3JpbWVfc3Vic2V0LCBwcmltYXJ5X3R5cGU9PSJOQVJDT1RJQ1MiKQp3ZWFwb25zX3Zpb2xhdGlvbiA8LSBzdWJzZXQoY2hpY2Fnb19jcmltZV9zdWJzZXQsIHByaW1hcnlfdHlwZT09IldFQVBPTlMgVklPTEFUSU9OIikKcm9iYmVyeSA8LSBzdWJzZXQoY2hpY2Fnb19jcmltZV9zdWJzZXQsIHByaW1hcnlfdHlwZT09IlJPQkJFUlkiKQpjcmltaW5hbF9kYW1hZ2UgPC0gc3Vic2V0KGNoaWNhZ29fY3JpbWVfc3Vic2V0LCBwcmltYXJ5X3R5cGU9PSJDUklNSU5BTCBEQU1BR0UiKQpkZWNlcHRpdmVfcHJhY3RpY2UgPC0gc3Vic2V0KGNoaWNhZ29fY3JpbWVfc3Vic2V0LCBwcmltYXJ5X3R5cGU9PSJERUNFUFRJVkUgUFJBQ1RJQ0UiKQoKYXNzYXVsdF90ciA8LSBzdWJzZXQoY2hpY2Fnb19jcmltZV9zdWJzZXRfdHIsIHByaW1hcnlfdHlwZT09IkFTU0FVTFQiKQp2aW9sZW50X3RyX2NyaW1lIDwtIHN1YnNldChjaGljYWdvX2NyaW1lX3N1YnNldF90ciwgcHJpbWFyeV90eXBlPT0iVklPTEVOVCBDUklNRSIpCnRoZWZ0X3RyIDwtIHN1YnNldChjaGljYWdvX2NyaW1lX3N1YnNldF90ciwgcHJpbWFyeV90eXBlPT0iVEhFRlQiKQpuYXJjb3RpY3NfdHIgPC0gc3Vic2V0KGNoaWNhZ29fY3JpbWVfc3Vic2V0X3RyLCBwcmltYXJ5X3R5cGU9PSJOQVJDT1RJQ1MiKQp3ZWFwb25zX3Zpb2xhdGlvbl90ciA8LSBzdWJzZXQoY2hpY2Fnb19jcmltZV9zdWJzZXRfdHIsIHByaW1hcnlfdHlwZT09IldFQVBPTlMgVklPTEFUSU9OIikKcm9iYmVyeV90ciA8LSBzdWJzZXQoY2hpY2Fnb19jcmltZV9zdWJzZXRfdHIsIHByaW1hcnlfdHlwZT09IlJPQkJFUlkiKQpjcmltaW5hbF9kYW1hZ2VfdHIgPC0gc3Vic2V0KGNoaWNhZ29fY3JpbWVfc3Vic2V0X3RyLCBwcmltYXJ5X3R5cGU9PSJDUklNSU5BTCBEQU1BR0UiKQpkZWNlcHRpdmVfcHJhY3RpY2VfdHIgPC0gc3Vic2V0KGNoaWNhZ29fY3JpbWVfc3Vic2V0X3RyLCBwcmltYXJ5X3R5cGU9PSJERUNFUFRJVkUgUFJBQ1RJQ0UiKQpgYGAKCiMjIERJU1RSSUNUUwoKYGBge3J9CmxpYnJhcnkoc3FsZGYpCgpkaXN0cmljdHNfdHJ1ZSA8LSBzcWxkZignU0VMRUNUIGRpc3RyaWN0LCBBVkcobGF0aXR1ZGUpIGFzIGF2Z19sYXRpdHVkZSxBVkcobG9uZ2l0dWRlKSBhcyBhdmdfbG9uZ2l0dWRlLCBjb3VudCgqKSBhcyBhcnJlc3QgRlJPTSBjaGljYWdvX2NyaW1lX3N1YnNldCBXSEVSRSBhcnJlc3QgTElLRSAiVHJ1ZSIgR1JPVVAgQlkgZGlzdHJpY3QgT1JERVIgQlkgZGlzdHJpY3QnKQpkaXN0cmljdHNfZmFsc2UgPC0gc3FsZGYoJ1NFTEVDVCBkaXN0cmljdCwgQVZHKGxhdGl0dWRlKSBhcyBhdmdfbGF0aXR1ZGUsQVZHKGxvbmdpdHVkZSkgYXMgYXZnX2xvbmdpdHVkZSwgY291bnQoKikgYXMgbm9fYXJyZXN0IEZST00gY2hpY2Fnb19jcmltZV9zdWJzZXQgV0hFUkUgYXJyZXN0IExJS0UgIkZhbHNlIiBHUk9VUCBCWSBkaXN0cmljdCBPUkRFUiBCWSBkaXN0cmljdCcpCmRpc3RyaWN0c190cnVlJGFycmVzdCA8LSBhcy5udW1lcmljKGRpc3RyaWN0c190cnVlJGFycmVzdCkKZGlzdHJpY3RzX2ZhbHNlJG5vX2FycmVzdCA8LSBhcy5udW1lcmljKGRpc3RyaWN0c19mYWxzZSRub19hcnJlc3QpCmRpc3RyaWN0c190cnVlCmRpc3RyaWN0c19mYWxzZQoKcG9saWNlX2Rpc3RyaWN0cyA8LSByZWFkLnRhYmxlKGZpbGUgPSAiUG9saWNlX1N0YXRpb25zLmNzdiIsICNOYW1lIG9mIHRleHQgZmlsZS4KICAgICAgICAgICAgICAgICAgICAgIHNlcCA9ICIsIiwgICAgICAgICAgICAgICAgICAgICAgICNTZXBhcmF0aW9uIGNoYXJhY3Rlci4KICAgICAgICAgICAgICAgICAgICAgIGhlYWRlciA9IFRSVUUsICAgICAgICAgICAgICAgICAgICNJZiBjb2x1bW4gbmFtZXMgYXJlIGluIHRoZSBmaXJzdCByb3cuCiAgICAgICAgICAgICAgICAgICAgICBuYS5zdHJpbmdzID0gIk5BIiwgICAgICAgICAgICAgICAjQ2hhcmFjdGVyIHRvIGJlIG1hcmtlZCBhcyBtaXNzaW5nIHZhbHVlLgogICAgICAgICAgICAgICAgICAgICAgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFKQpwb2xpY2VfZGlzdHJpY3RzCgpwb2xpY2VfZGlzdHJpY3RzJERJU1RSSUNUW3BvbGljZV9kaXN0cmljdHMkRElTVFJJQ1QgPT0gIkhlYWRxdWFydGVycyJdIDwtICIwIgpwb2xpY2VfZGlzdHJpY3RzJERJU1RSSUNUIDwtIGFzLmZhY3Rvcihwb2xpY2VfZGlzdHJpY3RzJERJU1RSSUNUKQoKZGlzdHJpY3RzIDwtIHNxbGRmKCdTRUxFQ1QgRElTVFJJQ1QgYXMgZGlzdHJpY3QsIExBVElUVURFIGFzIGxhdGl0dWRlLExPTkdJVFVERSBhcyBsb25naXR1ZGUgRlJPTSBwb2xpY2VfZGlzdHJpY3RzJykKCmFycmVzdF9wZXJjZW50YWdlIDwtIGRhdGEuZnJhbWUoJ0Rpc3RyaWN0JyA9IGRpc3RyaWN0c19mYWxzZSRkaXN0cmljdCwgJ1BjdEFycmVzdCcgPSBkaXN0cmljdHNfdHJ1ZSRhcnJlc3QvKGRpc3RyaWN0c190cnVlJGFycmVzdCArIGRpc3RyaWN0c19mYWxzZSRub19hcnJlc3QpLCAnQ3JpbWVzJyA9IChkaXN0cmljdHNfdHJ1ZSRhcnJlc3QgKyBkaXN0cmljdHNfZmFsc2Ukbm9fYXJyZXN0KSkKYXJyZXN0X3BlcmNlbnRhZ2UKCmdncGxvdChkYXRhID0gYXJyZXN0X3BlcmNlbnRhZ2UpICsKICBnZW9tX2NvbChtYXBwaW5nID0gYWVzKHggPSBEaXN0cmljdCwgeSA9IENyaW1lcykpICsKICBnZW9tX2xpbmUoYWVzKHggPSBEaXN0cmljdCwgeSA9IFBjdEFycmVzdCoxMDAwMCwgZ3JvdXAgPSAxKSwgY29sb3IgPSAieWVsbG93IikgKwogIHNjYWxlX3lfY29udGludW91cyhzZWMuYXhpcyA9IHNlY19heGlzKH4uLzEwMDAwLCBuYW1lID0gIlBjdEFycmVzdCIpKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoaGp1c3QgPSAxKSkKCiMjIElOSVRJQUxJWkUKbGlicmFyeSgibGVhZmxldCIpCmxpYnJhcnkoImRhdGEudGFibGUiKQpsaWJyYXJ5KCJzcCIpCmxpYnJhcnkoInJnZGFsIikKIyBsaWJyYXJ5KCJtYXB0b29scyIpCmxpYnJhcnkoIktlcm5TbW9vdGgiKQoKc2V0RFQoZGlzdHJpY3RzX2ZhbHNlKQoKI2RldnRvb2xzOjppbnN0YWxsX2dpdGh1YigiZGthaGxlL2dnbWFwIiwgcmVmID0gInRpZHl1cCIsIGZvcmNlID0gVFJVRSkKbGlicmFyeShnZ21hcCkKY2hpY2FnbyA8LSBnZXRfc3RhbWVubWFwKGJib3ggPSBjKGxlZnQgPSAtODguMDIyNSwgYm90dG9tID0gNDEuNTk0OSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByaWdodCA9IC04Ny4yNzEzLCB0b3AgPSA0Mi4wNjc3KSwgCiAgICAgICAgICAgICAgICAgICAgICAgICB6b29tID0gMTEpCmdnbWFwKGNoaWNhZ28pICsKZ2VvbV90ZXh0KGFlcyh4ID0gbG9uZ2l0dWRlLCB5ID0gbGF0aXR1ZGUsIGxhYmVsID0gZGlzdHJpY3QpLCBkYXRhID0gZGlzdHJpY3RzKQpgYGAKCgpgYGB7cn0KCmxpYnJhcnkoZ2dtYXApCmNoaWNhZ28gPC0gZ2V0X3N0YW1lbm1hcChiYm94ID0gYyhsZWZ0ID0gLTg4LjAyMjUsIGJvdHRvbSA9IDQxLjU5NDksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmlnaHQgPSAtODcuMjcxMywgdG9wID0gNDIuMDY3NyksIAogICAgICAgICAgICAgICAgICAgICAgICAgem9vbSA9IDExKQpnZ21hcChjaGljYWdvKSArCmdlb21fdGV4dChhZXMoeCA9IExPTkdJVFVERSwgeSA9IExBVElUVURFLCBsYWJlbCA9IERJU1RSSUNUKSwgZGF0YSA9IHBvbGljZV9kaXN0cmljdHMpCmBgYAoKYGBge3J9CmdncGxvdChkYXRhID0gYXNzYXVsdCkgKwogIGdlb21fYmFyKG1hcHBpbmcgPSBhZXMoeCA9IGRpc3RyaWN0KSkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMSkpICsKICBnZ3RpdGxlKCJBU1NBVUxUIEJZIERJU1RSSUNUIikKCmdncGxvdChkYXRhID0gdGhlZnQpICsKICBnZW9tX2JhcihtYXBwaW5nID0gYWVzKHggPSBkaXN0cmljdCkpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDEpKSArCiAgZ2d0aXRsZSgiVEhFRlRTIEJZIERJU1RSSUNUIikKCmdncGxvdChkYXRhID0gdmlvbGVudF9jcmltZSkgKwogIGdlb21fYmFyKG1hcHBpbmcgPSBhZXMoeCA9IGRpc3RyaWN0KSkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMSkpICsKICBnZ3RpdGxlKCJWSU9MRU5UIENSSU1FUyBCWSBESVNUUklDVCIpCgpnZ3Bsb3QoZGF0YSA9IG5hcmNvdGljcykgKwogIGdlb21fYmFyKG1hcHBpbmcgPSBhZXMoeCA9IGRpc3RyaWN0KSkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMSkpICsKICBnZ3RpdGxlKCJOQVJDT1RJQyBDUklNRVMgQlkgRElTVFJJQ1QiKQoKZ2dwbG90KGRhdGEgPSB3ZWFwb25zX3Zpb2xhdGlvbikgKwogIGdlb21fYmFyKG1hcHBpbmcgPSBhZXMoeCA9IGRpc3RyaWN0KSkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMSkpICsKICBnZ3RpdGxlKCJXRUFQT04tUkVMQVRFRCBDUklNRVMgQlkgRElTVFJJQ1QiKQoKZ2dwbG90KGRhdGEgPSByb2JiZXJ5KSArCiAgZ2VvbV9iYXIobWFwcGluZyA9IGFlcyh4ID0gZGlzdHJpY3QpKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoaGp1c3QgPSAxKSkgKwogIGdndGl0bGUoIlJPQkJFUklFUyBCWSBESVNUUklDVCIpCgpnZ3Bsb3QoZGF0YSA9IGNyaW1pbmFsX2RhbWFnZSkgKwogIGdlb21fYmFyKG1hcHBpbmcgPSBhZXMoeCA9IGRpc3RyaWN0KSkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMSkpICsKICBnZ3RpdGxlKCJDUklNSU5BTCBEQU1BR0UgQ1JJTUVTIEJZIERJU1RSSUNUIikKCmdncGxvdChkYXRhID0gZGVjZXB0aXZlX3ByYWN0aWNlKSArCiAgZ2VvbV9iYXIobWFwcGluZyA9IGFlcyh4ID0gZGlzdHJpY3QpKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoaGp1c3QgPSAxKSkgKwogIGdndGl0bGUoIkRFQ0VQVElWRSBQUkFDVElDRSBDUklNRVMgQlkgRElTVFJJQ1QiKQpgYGAKYGBge3J9CmxpYnJhcnkoZ2dwbG90MikKCmdncGxvdChkYXRhID0gY2hpY2Fnb19jcmltZV9zdWJzZXQsIGFlcyh4PXByaW1hcnlfdHlwZSwgeT1kaXN0cmljdCwgZmlsbD1hcnJlc3QpKSArIAogIGdlb21fdGlsZSgpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCBoanVzdCA9IDEpKQpgYGAKCmBgYHtyfQojIENvcnJlbGF0aW9uCmxpYnJhcnkoZ2dwbG90MikKZ2dwbG90KGNoaWNhZ29fY3JpbWVfc3Vic2V0LGFlcyh4PWRpc3RyaWN0LHk9cHJpbWFyeV90eXBlLGNvbG9yPWFycmVzdCkpK2dlb21fcG9pbnQoYWxwaGE9MC41KQpgYGAKCiMjIEFzc29jaWF0aW9uIFJ1bGVzCgpgYGB7cn0KY2hpY2Fnb19jcmltZV9zdWJzZXRfMiA8LSBzdWJzZXQoY2hpY2Fnb19jcmltZV9zdWJzZXQsIHNlbGVjdD0tYyhjYXNlX251bWJlcixibG9jayx3YXJkLGRlc2NyaXB0aW9uLGRheSxtb250aCxsYXRpdHVkZSxsb25naXR1ZGUpKQpjaGljYWdvX2NyaW1lX3N1YnNldF8yIDwtIHN1YnNldChjaGljYWdvX2NyaW1lX3N1YnNldF8yLCBzZWxlY3Q9LWMobG9jYXRpb25fZGVzY3JpcHRpb24pKQp3cml0ZS5jc3YoY2hpY2Fnb19jcmltZV9zdWJzZXRfMiwiY2hpY2Fnb19jcmltZV9BUi5jc3YiLCBxdW90ZSA9IEZBTFNFLCByb3cubmFtZXMgPSBGQUxTRSkKbGlicmFyeShhcnVsZXMpCmNyaW1lX3RyYW5zYWN0aW9ucyA8LSByZWFkLnRyYW5zYWN0aW9ucygiY2hpY2Fnb19jcmltZV9BUi5jc3YiLCBzZXA9IiwiKQoKI2RlY2VwdGl2ZV9wcmFjdGljZV8yIDwtIHN1YnNldChkZWNlcHRpdmVfcHJhY3RpY2UsIHNlbGVjdD0tYyhjYXNlX251bWJlcixibG9jayx3YXJkLGRlc2NyaXB0aW9uLGRheSxtb250aCxsYXRpdHVkZSxsb25naXR1ZGUpKQojd3JpdGUuY3N2KGRlY2VwdGl2ZV9wcmFjdGljZV8yLCJkZWNlcHRpdmVfcHJhY3RpY2UuY3N2IiwgcXVvdGUgPSBGQUxTRSwgcm93Lm5hbWVzID0gRkFMU0UpCiNkcF90cmFuc2FjdGlvbnMgPC0gcmVhZC50cmFuc2FjdGlvbnMoImRlY2VwdGl2ZV9wcmFjdGljZS5jc3YiLCBzZXA9IiwiKQpgYGAKYGBge3J9CmlmICghcmVxdWlyZSgiUkNvbG9yQnJld2VyIikpIHsKICAjIGluc3RhbGwgY29sb3IgcGFja2FnZSBvZiBSCiAgaW5zdGFsbC5wYWNrYWdlcygiUkNvbG9yQnJld2VyIikKICAjaW5jbHVkZSBsaWJyYXJ5IFJDb2xvckJyZXdlcgogIGxpYnJhcnkoUkNvbG9yQnJld2VyKQp9CgppdGVtRnJlcXVlbmN5UGxvdChjcmltZV90cmFuc2FjdGlvbnMsdG9wTj0yMCx0eXBlPSJhYnNvbHV0ZSIsCiAgICAgICAgICAgICAgICAgIGNvbD1icmV3ZXIucGFsKDgsJ1Bhc3RlbDInKSwgCiAgICAgICAgICAgICAgICAgIG1haW49IkFic29sdXRlIEl0ZW0gRnJlcXVlbmN5IFBsb3QiKQpgYGAKIyMgUmVnbGFzIGRlIEFzb2NpYWNpb24gR2VuZXJhbApgYGB7cn0KIyBSdWxlIEdFTkVSQVRJT04KYXNzb2NpYXRpb24ucnVsZXMuY2xlYW4gPC0gYXByaW9yaShjcmltZV90cmFuc2FjdGlvbnMsIHBhcmFtZXRlciA9IGxpc3Qoc3VwcD0wLjAwMSwgY29uZj0wLjcpKQpzdWJzZXQucnVsZXMuY2xlYW4gPC0gd2hpY2goY29sU3Vtcyhpcy5zdWJzZXQoYXNzb2NpYXRpb24ucnVsZXMuY2xlYW4sIGFzc29jaWF0aW9uLnJ1bGVzLmNsZWFuKSkgPiAxKQpzdWJzZXQuYXNzb2NpYXRpb24ucnVsZXMuY2xlYW4uIDwtIGFzc29jaWF0aW9uLnJ1bGVzLmNsZWFuWy1zdWJzZXQucnVsZXMuY2xlYW5dCmluc3BlY3Qoc3Vic2V0LmFzc29jaWF0aW9uLnJ1bGVzLmNsZWFuLikKCnJ1bGVzX2J5X2NvdW50IDwtIHNvcnQoYXNzb2NpYXRpb24ucnVsZXMuY2xlYW4sIGJ5ID0gImNvdW50IikKcnVsZXNfYnlfY29uZiA8LSBzb3J0KGFzc29jaWF0aW9uLnJ1bGVzLmNsZWFuLCBieSA9ICJjb25maWRlbmNlIikKcnVsZXNfYnlfc3VwcCA8LSBzb3J0KGFzc29jaWF0aW9uLnJ1bGVzLmNsZWFuLCBieSA9ICJsaWZ0IikKaW5zcGVjdChydWxlc19ieV9jb3VudCkKaW5zcGVjdChydWxlc19ieV9jb25mKQppbnNwZWN0KHJ1bGVzX2J5X3N1cHApCmBgYApgYGB7cn0KIyBSdWxlIEdFTkVSQVRJT04KYXNzYXVsdC5hc3NvY2lhdGlvbi5ydWxlcyA8LSBhcHJpb3JpKGNyaW1lX3RyYW5zYWN0aW9ucywgcGFyYW1ldGVyID0gCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaXN0KHN1cHA9MC4wMDEsIGNvbmY9MC4xKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcHBlYXJhbmNlID0gbGlzdChkZWZhdWx0PSJsaHMiLHJocz0iQVNTQVVMVCIpKQojIEJvcnJhciByZWdsYXMgcmVkdW5kYW50ZXMKYXNzYXVsdC5zdWJzZXQucnVsZXMgPC0gd2hpY2goY29sU3Vtcyhpcy5zdWJzZXQoYXNzYXVsdC5hc3NvY2lhdGlvbi5ydWxlcywgYXNzYXVsdC5hc3NvY2lhdGlvbi5ydWxlcykpID4gMSkgIyBnZXQgc3Vic2V0IHJ1bGVzIGluIHZlY3Rvcgphc3NhdWx0LnN1YnNldC5hc3NvY2lhdGlvbi5ydWxlcy4gPC0gYXNzYXVsdC5hc3NvY2lhdGlvbi5ydWxlc1stYXNzYXVsdC5zdWJzZXQucnVsZXNdICMgcmVtb3ZlIHN1YnNldCBydWxlcy4KaW5zcGVjdChhc3NhdWx0LnN1YnNldC5hc3NvY2lhdGlvbi5ydWxlcy4pCgphc19ieV9jb3VudCA8LSBzb3J0KGFzc2F1bHQuYXNzb2NpYXRpb24ucnVsZXMsIGJ5ID0gImNvdW50IikKYXNfYnlfY29uZiA8LSBzb3J0KGFzc2F1bHQuYXNzb2NpYXRpb24ucnVsZXMsIGJ5ID0gImNvbmZpZGVuY2UiKQojZHBfYnlfc3VwcCA8LSBzb3J0KGRwLnN1YnNldC5hc3NvY2lhdGlvbi5ydWxlcy4sIGJ5ID0gInN1cHBvcnQiKQppbnNwZWN0KGFzX2J5X2NvdW50KQppbnNwZWN0KGFzX2J5X2NvbmYpCiNpbnNwZWN0KGRwX2J5X3N1cHApCmBgYApgYGB7cn0KIyBSdWxlIEdFTkVSQVRJT04KY2QuYXNzb2NpYXRpb24ucnVsZXMgPC0gYXByaW9yaShjcmltZV90cmFuc2FjdGlvbnMsIHBhcmFtZXRlciA9IAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGlzdChzdXBwPTAuMDAxLCBjb25mPTAuMSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcHBlYXJhbmNlID0gbGlzdChkZWZhdWx0PSJsaHMiLHJocz0iQ1JJTUlOQUwgREFNQUdFIikpCiMgQm9ycmFyIHJlZ2xhcyByZWR1bmRhbnRlcwpjZC5zdWJzZXQucnVsZXMgPC0gd2hpY2goY29sU3Vtcyhpcy5zdWJzZXQoY2QuYXNzb2NpYXRpb24ucnVsZXMsIGNkLmFzc29jaWF0aW9uLnJ1bGVzKSkgPiAxKSAjIGdldCBzdWJzZXQgcnVsZXMgaW4gdmVjdG9yCmNkLnN1YnNldC5hc3NvY2lhdGlvbi5ydWxlcy4gPC0gY2QuYXNzb2NpYXRpb24ucnVsZXNbLWNkLnN1YnNldC5ydWxlc10gIyByZW1vdmUgc3Vic2V0IHJ1bGVzLgppbnNwZWN0KGNkLmFzc29jaWF0aW9uLnJ1bGVzKQoKY2RfYnlfY291bnQgPC0gc29ydChjZC5hc3NvY2lhdGlvbi5ydWxlcywgYnkgPSAiY291bnQiKQpjZF9ieV9jb25mIDwtIHNvcnQoY2QuYXNzb2NpYXRpb24ucnVsZXMsIGJ5ID0gImNvbmZpZGVuY2UiKQojZHBfYnlfc3VwcCA8LSBzb3J0KGRwLnN1YnNldC5hc3NvY2lhdGlvbi5ydWxlcy4sIGJ5ID0gInN1cHBvcnQiKQppbnNwZWN0KGNkX2J5X2NvdW50KQppbnNwZWN0KGNkX2J5X2NvbmYpCiNpbnNwZWN0KGRwX2J5X3N1cHApCmBgYApgYGB7cn0KIyBSdWxlIEdFTkVSQVRJT04KZHAuYXNzb2NpYXRpb24ucnVsZXMgPC0gYXByaW9yaShjcmltZV90cmFuc2FjdGlvbnMsIHBhcmFtZXRlciA9IAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGlzdChzdXBwPTAuMDAxLCBjb25mPTAuMSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcHBlYXJhbmNlID0gbGlzdChkZWZhdWx0PSJsaHMiLHJocz0iREVDRVBUSVZFIFBSQUNUSUNFIikpCiMgQm9ycmFyIHJlZ2xhcyByZWR1bmRhbnRlcwpkcC5zdWJzZXQucnVsZXMgPC0gd2hpY2goY29sU3Vtcyhpcy5zdWJzZXQoZHAuYXNzb2NpYXRpb24ucnVsZXMsIGRwLmFzc29jaWF0aW9uLnJ1bGVzKSkgPiAxKSAjIGdldCBzdWJzZXQgcnVsZXMgaW4gdmVjdG9yCmRwLnN1YnNldC5hc3NvY2lhdGlvbi5ydWxlcy4gPC0gZHAuYXNzb2NpYXRpb24ucnVsZXNbLWRwLnN1YnNldC5ydWxlc10gIyByZW1vdmUgc3Vic2V0IHJ1bGVzLgppbnNwZWN0KGRwLnN1YnNldC5hc3NvY2lhdGlvbi5ydWxlcy4pCgpkcF9ieV9jb3VudCA8LSBzb3J0KGRwLnN1YnNldC5hc3NvY2lhdGlvbi5ydWxlcy4sIGJ5ID0gImNvdW50IikKZHBfYnlfY29uZiA8LSBzb3J0KGRwLnN1YnNldC5hc3NvY2lhdGlvbi5ydWxlcy4sIGJ5ID0gImNvbmZpZGVuY2UiKQojZHBfYnlfc3VwcCA8LSBzb3J0KGRwLnN1YnNldC5hc3NvY2lhdGlvbi5ydWxlcy4sIGJ5ID0gInN1cHBvcnQiKQppbnNwZWN0KGRwX2J5X2NvdW50KQppbnNwZWN0KGRwX2J5X2NvbmYpCiNpbnNwZWN0KGRwX2J5X3N1cHApCmBgYApgYGB7cn0KbmFyY290aWNzX2NsZWFuLmFzc29jaWF0aW9uLnJ1bGVzIDwtIGFwcmlvcmkoY3JpbWVfdHJhbnNhY3Rpb25zLCBwYXJhbWV0ZXIgPSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpc3Qoc3VwcD0wLjAwMSwgY29uZj0wLjEpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFwcGVhcmFuY2UgPSBsaXN0KGRlZmF1bHQ9ImxocyIscmhzPSJOQVJDT1RJQ1MiKSkKIyBCb3JyYXIgcmVnbGFzIHJlZHVuZGFudGVzCm5hcmNvdGljc19jbGVhbi5zdWJzZXQucnVsZXMgPC0gd2hpY2goY29sU3Vtcyhpcy5zdWJzZXQobmFyY290aWNzX2NsZWFuLmFzc29jaWF0aW9uLnJ1bGVzLCBuYXJjb3RpY3NfY2xlYW4uYXNzb2NpYXRpb24ucnVsZXMpKSA+IDEpICMgZ2V0IHN1YnNldCBydWxlcyBpbiB2ZWN0b3IKbmFyY290aWNzX2NsZWFuLnN1YnNldC5hc3NvY2lhdGlvbi5ydWxlcy4gPC0gbmFyY290aWNzX2NsZWFuLmFzc29jaWF0aW9uLnJ1bGVzWy1uYXJjb3RpY3NfY2xlYW4uc3Vic2V0LnJ1bGVzXSAjIHJlbW92ZSBzdWJzZXQgcnVsZXMuCmluc3BlY3QobmFyY290aWNzX2NsZWFuLnN1YnNldC5hc3NvY2lhdGlvbi5ydWxlcy4pCgpuYXJjX2J5X2NvdW50IDwtIHNvcnQobmFyY290aWNzX2NsZWFuLmFzc29jaWF0aW9uLnJ1bGVzLCBieSA9ICJjb3VudCIpCm5hcmNfYnlfY29uZiA8LSBzb3J0KG5hcmNvdGljc19jbGVhbi5hc3NvY2lhdGlvbi5ydWxlcywgYnkgPSAiY29uZmlkZW5jZSIpCiNkcF9ieV9zdXBwIDwtIHNvcnQoZHAuc3Vic2V0LmFzc29jaWF0aW9uLnJ1bGVzLiwgYnkgPSAic3VwcG9ydCIpCmluc3BlY3QobmFyY19ieV9jb3VudCkKaW5zcGVjdChuYXJjX2J5X2NvbmYpCiNpbnNwZWN0KGRwX2J5X3N1cHApCmBgYApgYGB7cn0Kcm9iYmVyeS5hc3NvY2lhdGlvbi5ydWxlcyA8LSBhcHJpb3JpKGNyaW1lX3RyYW5zYWN0aW9ucywgcGFyYW1ldGVyID0gCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaXN0KHN1cHA9MC4wMDEsIGNvbmY9MC4xNSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXBwZWFyYW5jZSA9IGxpc3QoZGVmYXVsdD0ibGhzIixyaHM9IlJPQkJFUlkiKSkKIyBCb3JyYXIgcmVnbGFzIHJlZHVuZGFudGVzCnJvYmJlcnkuc3Vic2V0LnJ1bGVzIDwtIHdoaWNoKGNvbFN1bXMoaXMuc3Vic2V0KHJvYmJlcnkuYXNzb2NpYXRpb24ucnVsZXMsIHJvYmJlcnkuYXNzb2NpYXRpb24ucnVsZXMpKSA+IDEpIApyb2JiZXJ5LnN1YnNldC5hc3NvY2lhdGlvbi5ydWxlcy4gPC0gcm9iYmVyeS5hc3NvY2lhdGlvbi5ydWxlc1stcm9iYmVyeS5zdWJzZXQucnVsZXNdICMgcmVtb3ZlIHN1YnNldCBydWxlcy4KaW5zcGVjdChyb2JiZXJ5LmFzc29jaWF0aW9uLnJ1bGVzKQoKcm9iX2J5X2NvdW50IDwtIHNvcnQocm9iYmVyeS5hc3NvY2lhdGlvbi5ydWxlcywgYnkgPSAiY291bnQiKQpyb2JfYnlfY29uZiA8LSBzb3J0KHJvYmJlcnkuYXNzb2NpYXRpb24ucnVsZXMsIGJ5ID0gImNvbmZpZGVuY2UiKQojZHBfYnlfc3VwcCA8LSBzb3J0KGRwLnN1YnNldC5hc3NvY2lhdGlvbi5ydWxlcy4sIGJ5ID0gInN1cHBvcnQiKQppbnNwZWN0KHJvYl9ieV9jb3VudCkKaW5zcGVjdChyb2JfYnlfY29uZikKI2luc3BlY3QoZHBfYnlfc3VwcCkKYGBgCmBgYHtyfQp0aGVmdC5hc3NvY2lhdGlvbi5ydWxlcyA8LSBhcHJpb3JpKGNyaW1lX3RyYW5zYWN0aW9ucywgcGFyYW1ldGVyID0gCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaXN0KHN1cHA9MC4wMDUsIGNvbmY9MC41KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcHBlYXJhbmNlID0gbGlzdChkZWZhdWx0PSJsaHMiLHJocz0iVEhFRlQiKSkKIyBCb3JyYXIgcmVnbGFzIHJlZHVuZGFudGVzCnRoZWZ0LnN1YnNldC5ydWxlcyA8LSB3aGljaChjb2xTdW1zKGlzLnN1YnNldCh0aGVmdC5hc3NvY2lhdGlvbi5ydWxlcywgdGhlZnQuYXNzb2NpYXRpb24ucnVsZXMpKSA+IDEpIAp0aGVmdC5zdWJzZXQuYXNzb2NpYXRpb24ucnVsZXMuIDwtIHRoZWZ0LmFzc29jaWF0aW9uLnJ1bGVzWy10aGVmdC5zdWJzZXQucnVsZXNdICMgcmVtb3ZlIHN1YnNldCBydWxlcy4KaW5zcGVjdCh0aGVmdC5zdWJzZXQuYXNzb2NpYXRpb24ucnVsZXMuKQoKdGhlZnRfYnlfY291bnQgPC0gc29ydCh0aGVmdC5hc3NvY2lhdGlvbi5ydWxlcywgYnkgPSAiY291bnQiKQp0aGVmdF9ieV9jb25mIDwtIHNvcnQodGhlZnQuYXNzb2NpYXRpb24ucnVsZXMsIGJ5ID0gImNvbmZpZGVuY2UiKQojZHBfYnlfc3VwcCA8LSBzb3J0KGRwLnN1YnNldC5hc3NvY2lhdGlvbi5ydWxlcy4sIGJ5ID0gInN1cHBvcnQiKQppbnNwZWN0KHRoZWZ0X2J5X2NvdW50KQppbnNwZWN0KHRoZWZ0X2J5X2NvbmYpCiNpbnNwZWN0KGRwX2J5X3N1cHApCmBgYApgYGB7cn0KdmMuYXNzb2NpYXRpb24ucnVsZXMgPC0gYXByaW9yaShjcmltZV90cmFuc2FjdGlvbnMsIHBhcmFtZXRlciA9IAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGlzdChzdXBwPTAuMDAxLCBjb25mPTAuMTUpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFwcGVhcmFuY2UgPSBsaXN0KGRlZmF1bHQ9ImxocyIscmhzPSJWSU9MRU5UIENSSU1FIikpCiMgQm9ycmFyIHJlZ2xhcyByZWR1bmRhbnRlcwp2Yy5zdWJzZXQucnVsZXMgPC0gd2hpY2goY29sU3Vtcyhpcy5zdWJzZXQodmMuYXNzb2NpYXRpb24ucnVsZXMsIHZjLmFzc29jaWF0aW9uLnJ1bGVzKSkgPiAxKSAjIGdldCBzdWJzZXQgcnVsZXMgaW4gIAp2Yy5zdWJzZXQuYXNzb2NpYXRpb24ucnVsZXMuIDwtIHZjLmFzc29jaWF0aW9uLnJ1bGVzWy12Yy5zdWJzZXQucnVsZXNdICMgcmVtb3ZlIHN1YnNldCBydWxlcy4KaW5zcGVjdCh2Yy5zdWJzZXQuYXNzb2NpYXRpb24ucnVsZXMuKQoKdmNfYnlfY291bnQgPC0gc29ydCh2Yy5hc3NvY2lhdGlvbi5ydWxlcywgYnkgPSAiY291bnQiKQp2Y19ieV9jb25mIDwtIHNvcnQodmMuYXNzb2NpYXRpb24ucnVsZXMsIGJ5ID0gImNvbmZpZGVuY2UiKQojdmNfYnlfc3VwcCA8LSBzb3J0KHZjLnN1YnNldC5hc3NvY2lhdGlvbi5ydWxlcy4sIGJ5ID0gInN1cHBvcnQiKQppbnNwZWN0KHZjX2J5X2NvdW50KQppbnNwZWN0KHZjX2J5X2NvbmYpCiNpbnNwZWN0KHd2X2J5X3N1cHApCmBgYApgYGB7cn0Kd3YuYXNzb2NpYXRpb24ucnVsZXMgPC0gYXByaW9yaShjcmltZV90cmFuc2FjdGlvbnMscGFyYW1ldGVyID0gCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGlzdChzdXBwPTAuMDAxLCBjb25mPTAuMSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXBwZWFyYW5jZSA9IGxpc3QoZGVmYXVsdD0ibGhzIixyaHM9IldFQVBPTlMgVklPTEFUSU9OIikpCiMgQm9ycmFyIHJlZ2xhcyByZWR1bmRhbnRlcwp3di5zdWJzZXQucnVsZXMgPC0gd2hpY2goY29sU3Vtcyhpcy5zdWJzZXQod3YuYXNzb2NpYXRpb24ucnVsZXMsIHd2LmFzc29jaWF0aW9uLnJ1bGVzKSkgPiAxKSAjIGdldCBzdWJzZXQgcnVsZXMgaW4gIAp3di5zdWJzZXQuYXNzb2NpYXRpb24ucnVsZXMuIDwtIHd2LmFzc29jaWF0aW9uLnJ1bGVzWy13di5zdWJzZXQucnVsZXNdICMgcmVtb3ZlIHN1YnNldCBydWxlcy4KaW5zcGVjdCh3di5zdWJzZXQuYXNzb2NpYXRpb24ucnVsZXMuKQoKd3ZfYnlfY291bnQgPC0gc29ydCh3di5hc3NvY2lhdGlvbi5ydWxlcywgYnkgPSAiY291bnQiKQp3dl9ieV9jb25mIDwtIHNvcnQod3YuYXNzb2NpYXRpb24ucnVsZXMsIGJ5ID0gImNvbmZpZGVuY2UiKQojd3ZfYnlfc3VwcCA8LSBzb3J0KHd2LnN1YnNldC5hc3NvY2lhdGlvbi5ydWxlcy4sIGJ5ID0gInN1cHBvcnQiKQppbnNwZWN0KHd2X2J5X2NvdW50KQppbnNwZWN0KHd2X2J5X2NvbmYpCiNpbnNwZWN0KHd2X2J5X3N1cHApCmBgYApgYGB7cn0KdHJ1ZS5hc3NvY2lhdGlvbi5ydWxlcyA8LSBhcHJpb3JpKGNyaW1lX3RyYW5zYWN0aW9ucyxwYXJhbWV0ZXIgPSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaXN0KHN1cHA9MC4wMDEsIGNvbmY9MC41KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcHBlYXJhbmNlID0gbGlzdChkZWZhdWx0PSJsaHMiLHJocz0iVHJ1ZSIpKQojIEJvcnJhciByZWdsYXMgcmVkdW5kYW50ZXMKdHJ1ZS5zdWJzZXQucnVsZXMgPC0gd2hpY2goY29sU3Vtcyhpcy5zdWJzZXQodHJ1ZS5hc3NvY2lhdGlvbi5ydWxlcywgdHJ1ZS5hc3NvY2lhdGlvbi5ydWxlcykpID4gMSkgIyBnZXQgc3Vic2V0IHJ1bGVzIGluICAKdHJ1ZS5zdWJzZXQuYXNzb2NpYXRpb24ucnVsZXMuIDwtIHRydWUuYXNzb2NpYXRpb24ucnVsZXNbLXRydWUuc3Vic2V0LnJ1bGVzXSAjIHJlbW92ZSBzdWJzZXQgcnVsZXMuCmluc3BlY3QodHJ1ZS5zdWJzZXQuYXNzb2NpYXRpb24ucnVsZXMuKQoKdF9ieV9jb3VudCA8LSBzb3J0KHRydWUuc3Vic2V0LmFzc29jaWF0aW9uLnJ1bGVzLiwgYnkgPSAiY291bnQiKQp0X2J5X2NvbmYgPC0gc29ydCh0cnVlLnN1YnNldC5hc3NvY2lhdGlvbi5ydWxlcy4sIGJ5ID0gImNvbmZpZGVuY2UiKQojd3ZfYnlfc3VwcCA8LSBzb3J0KHd2LnN1YnNldC5hc3NvY2lhdGlvbi5ydWxlcy4sIGJ5ID0gInN1cHBvcnQiKQppbnNwZWN0KHRfYnlfY291bnQpCmluc3BlY3QodF9ieV9jb25mKQojaW5zcGVjdCh3dl9ieV9zdXBwKQpgYGAKYGBge3J9CmZhbHNlLmFzc29jaWF0aW9uLnJ1bGVzIDwtIGFwcmlvcmkoY3JpbWVfdHJhbnNhY3Rpb25zLHBhcmFtZXRlciA9IAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpc3Qoc3VwcD0wLjAwMSwgY29uZj0wLjgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFwcGVhcmFuY2UgPSBsaXN0KGRlZmF1bHQ9ImxocyIscmhzPSJGYWxzZSIpKQojIEJvcnJhciByZWdsYXMgcmVkdW5kYW50ZXMKZmFsc2Uuc3Vic2V0LnJ1bGVzIDwtIHdoaWNoKGNvbFN1bXMoaXMuc3Vic2V0KGZhbHNlLmFzc29jaWF0aW9uLnJ1bGVzLCBmYWxzZS5hc3NvY2lhdGlvbi5ydWxlcykpID4gMSkgIyBnZXQgc3Vic2V0IHJ1bGVzIGluICAKZmFsc2Uuc3Vic2V0LmFzc29jaWF0aW9uLnJ1bGVzLiA8LSBmYWxzZS5hc3NvY2lhdGlvbi5ydWxlc1stZmFsc2Uuc3Vic2V0LnJ1bGVzXSAjIHJlbW92ZSBzdWJzZXQgcnVsZXMuCmluc3BlY3QoZmFsc2Uuc3Vic2V0LmFzc29jaWF0aW9uLnJ1bGVzLikKCmZfYnlfY291bnQgPC0gc29ydChmYWxzZS5hc3NvY2lhdGlvbi5ydWxlcywgYnkgPSAiY291bnQiKQpmX2J5X2NvbmYgPC0gc29ydChmYWxzZS5hc3NvY2lhdGlvbi5ydWxlcywgYnkgPSAiY29uZmlkZW5jZSIpCiN3dl9ieV9zdXBwIDwtIHNvcnQod3Yuc3Vic2V0LmFzc29jaWF0aW9uLnJ1bGVzLiwgYnkgPSAic3VwcG9ydCIpCmluc3BlY3QoZl9ieV9jb3VudCkKaW5zcGVjdChmX2J5X2NvbmYpCiNpbnNwZWN0KHd2X2J5X3N1cHApCmBgYApgYGB7cn0Kb2Noby5hc3NvY2lhdGlvbi5ydWxlcyA8LSBhcHJpb3JpKGNyaW1lX3RyYW5zYWN0aW9ucyxwYXJhbWV0ZXIgPSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaXN0KHN1cHA9MC4wMDAxLCBjb25mPTAuMDEpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFwcGVhcmFuY2UgPSBsaXN0KGRlZmF1bHQ9ImxocyIscmhzPSI4IikpCiMgQm9ycmFyIHJlZ2xhcyByZWR1bmRhbnRlcwpvY2hvLnN1YnNldC5ydWxlcyA8LSB3aGljaChjb2xTdW1zKGlzLnN1YnNldChvY2hvLmFzc29jaWF0aW9uLnJ1bGVzLCBvY2hvLmFzc29jaWF0aW9uLnJ1bGVzKSkgPiAxKSAjIGdldCBzdWJzZXQgcnVsZXMgaW4gIApvY2hvLnN1YnNldC5hc3NvY2lhdGlvbi5ydWxlcy4gPC0gb2Noby5hc3NvY2lhdGlvbi5ydWxlc1stb2Noby5zdWJzZXQucnVsZXNdICMgcmVtb3ZlIHN1YnNldCBydWxlcy4KaW5zcGVjdChvY2hvLnN1YnNldC5hc3NvY2lhdGlvbi5ydWxlcy4pCgpvY2hvX2J5X2NvdW50IDwtIHNvcnQob2Noby5hc3NvY2lhdGlvbi5ydWxlcywgYnkgPSAiY291bnQiKQpvY2hvX2J5X2NvbmYgPC0gc29ydChvY2hvLmFzc29jaWF0aW9uLnJ1bGVzLCBieSA9ICJjb25maWRlbmNlIikKI3d2X2J5X3N1cHAgPC0gc29ydCh3di5zdWJzZXQuYXNzb2NpYXRpb24ucnVsZXMuLCBieSA9ICJzdXBwb3J0IikKaW5zcGVjdChvY2hvX2J5X2NvdW50KQppbnNwZWN0KG9jaG9fYnlfY29uZikKI2luc3BlY3Qod3ZfYnlfc3VwcCkKYGBgCgpgYGB7cn0KIyMgR1JBRklDT1MgCiMjIERhdGFzZXQgRW50ZXJvCmxpYnJhcnkoYXJ1bGVzVml6KQojIEZpbHRlciBydWxlcyB3aXRoIGNvbmZpZGVuY2UgZ3JlYXRlciB0aGFuIDAuNCBvciA0MCUKc3ViUnVsZXM8LWFzc29jaWF0aW9uLnJ1bGVzLmNsZWFuW3F1YWxpdHkoYXNzb2NpYXRpb24ucnVsZXMuY2xlYW4pJGNvbmZpZGVuY2U+MC43XQojUGxvdCBTdWJSdWxlcwpwbG90KHN1YlJ1bGVzLG1ldGhvZD0idHdvLWtleSBwbG90IikKCiMjIFNlbGVjY2lvbmFtb3MgdW4gbnVtZXJvIGxpbWl0YWRvIGRlIHJlZ2xhcyBlbiBlbCBkYXRhc2V0IGxpbXBpbwp0b3AxMHN1YlJ1bGVzIDwtIGhlYWQoc3ViUnVsZXMsIG4gPSAyNSwgYnkgPSAiY29uZmlkZW5jZSIpCgojIE5vdywgcGxvdCBhbiBpbnRlcmFjdGl2ZSBncmFwaDoKI05vdGU6IFlvdSBjYW4gbWFrZSBhbGwgeW91ciBwbG90cyBpbnRlcmFjdGl2ZSB1c2luZyBlbmdpbmU9aHRtbHdpZGdldCBwYXJhbWV0ZXIgaW4gcGxvdApwbG90KHRvcDEwc3ViUnVsZXMsIG1ldGhvZCA9ICJncmFwaCIsICBlbmdpbmUgPSAiaHRtbHdpZGdldCIpCgojIyBJbmRpdmlkdWFsIFJ1bGUgUmVwcmVzZW50YXRpb24gRGF0YXNldCBMaW1waW8KIyBGaWx0ZXIgdG9wIDIwIHJ1bGVzIHdpdGggaGlnaGVzdCBsaWZ0CnN1YlJ1bGVzMjwtaGVhZChzdWJSdWxlcywgbj0yNSwgYnk9ImNvbmZpZGVuY2UiKQpwbG90KHN1YlJ1bGVzMiwgbWV0aG9kPSJwYXJhY29vcmQiKQoKYGBgCmBgYHtyfQojUGxvdCBTdWJSdWxlcwpwbG90KGFzc2F1bHQuc3Vic2V0LmFzc29jaWF0aW9uLnJ1bGVzLixtZXRob2Q9InR3by1rZXkgcGxvdCIpCgojIyBTZWxlY2Npb25hbW9zIHVuIG51bWVybyBsaW1pdGFkbyBkZSByZWdsYXMgZW4gZWwgZGF0YXNldCBsaW1waW8KdG9wMTBzdWJSdWxlcyA8LSBoZWFkKGFzc2F1bHQuc3Vic2V0LmFzc29jaWF0aW9uLnJ1bGVzLiwgbiA9IDIwLCBieSA9ICJjb25maWRlbmNlIikKaW5zcGVjdCh0b3AxMHN1YlJ1bGVzKQojIE5vdywgcGxvdCBhbiBpbnRlcmFjdGl2ZSBncmFwaDoKI05vdGU6IFlvdSBjYW4gbWFrZSBhbGwgeW91ciBwbG90cyBpbnRlcmFjdGl2ZSB1c2luZyBlbmdpbmU9aHRtbHdpZGdldCBwYXJhbWV0ZXIgaW4gcGxvdApwbG90KGFzc2F1bHQuc3Vic2V0LmFzc29jaWF0aW9uLnJ1bGVzLiwgbWV0aG9kID0gImdyYXBoIiwgIGVuZ2luZSA9ICJodG1sd2lkZ2V0IikKCiMjIEluZGl2aWR1YWwgUnVsZSBSZXByZXNlbnRhdGlvbiBEYXRhc2V0IExpbXBpbwojIEZpbHRlciB0b3AgMjAgcnVsZXMgd2l0aCBoaWdoZXN0IGxpZnQKc3ViUnVsZXMyPC1oZWFkKGFzc2F1bHQuc3Vic2V0LmFzc29jaWF0aW9uLnJ1bGVzLiwgbj0yMCwgYnk9ImNvbmZpZGVuY2UiKQpwbG90KHRvcDEwc3ViUnVsZXMsIG1ldGhvZD0icGFyYWNvb3JkIikKYGBgCmBgYHtyfQojUGxvdCBTdWJSdWxlcwpwbG90KGNkLmFzc29jaWF0aW9uLnJ1bGVzLG1ldGhvZD0idHdvLWtleSBwbG90IikKCnN1YlJ1bGVzX2NkPC1jZC5hc3NvY2lhdGlvbi5ydWxlc1txdWFsaXR5KGNkLmFzc29jaWF0aW9uLnJ1bGVzKSRjb25maWRlbmNlPjAuMl0KCiMjIFNlbGVjY2lvbmFtb3MgdW4gbnVtZXJvIGxpbWl0YWRvIGRlIHJlZ2xhcyBlbiBlbCBkYXRhc2V0IGxpbXBpbwp0b3AxMHN1YlJ1bGVzIDwtIGhlYWQoY2QuYXNzb2NpYXRpb24ucnVsZXMsIG4gPSAxMCwgYnkgPSAiY29uZmlkZW5jZSIpCmluc3BlY3QodG9wMTBzdWJSdWxlcykKIyBOb3csIHBsb3QgYW4gaW50ZXJhY3RpdmUgZ3JhcGg6CiNOb3RlOiBZb3UgY2FuIG1ha2UgYWxsIHlvdXIgcGxvdHMgaW50ZXJhY3RpdmUgdXNpbmcgZW5naW5lPWh0bWx3aWRnZXQgcGFyYW1ldGVyIGluIHBsb3QKcGxvdChzdWJSdWxlc19jZCwgbWV0aG9kID0gImdyYXBoIiwgIGVuZ2luZSA9ICJodG1sd2lkZ2V0IikKCiMjIEluZGl2aWR1YWwgUnVsZSBSZXByZXNlbnRhdGlvbiBEYXRhc2V0IExpbXBpbwojIEZpbHRlciB0b3AgMjAgcnVsZXMgd2l0aCBoaWdoZXN0IGxpZnQKc3ViUnVsZXMyPC1oZWFkKHN1YlJ1bGVzX2NkLCBuPTI1LCBieT0iY29uZmlkZW5jZSIpCnBsb3QodG9wMTBzdWJSdWxlcywgbWV0aG9kPSJwYXJhY29vcmQiKQpgYGAKYGBge3J9CiNQbG90IFN1YlJ1bGVzCnBsb3QoZHAuYXNzb2NpYXRpb24ucnVsZXMsbWV0aG9kPSJ0d28ta2V5IHBsb3QiKQoKc3ViUnVsZXNfZHA8LWRwLmFzc29jaWF0aW9uLnJ1bGVzW3F1YWxpdHkoZHAuYXNzb2NpYXRpb24ucnVsZXMpJGNvbmZpZGVuY2U+MC4xXQoKIyMgU2VsZWNjaW9uYW1vcyB1biBudW1lcm8gbGltaXRhZG8gZGUgcmVnbGFzIGVuIGVsIGRhdGFzZXQgbGltcGlvCnRvcDEwc3ViUnVsZXMgPC0gaGVhZChkcC5hc3NvY2lhdGlvbi5ydWxlcywgbiA9IDEwLCBieSA9ICJjb3VudCIpCgojIE5vdywgcGxvdCBhbiBpbnRlcmFjdGl2ZSBncmFwaDoKI05vdGU6IFlvdSBjYW4gbWFrZSBhbGwgeW91ciBwbG90cyBpbnRlcmFjdGl2ZSB1c2luZyBlbmdpbmU9aHRtbHdpZGdldCBwYXJhbWV0ZXIgaW4gcGxvdApwbG90KHN1YlJ1bGVzX2RwLCBtZXRob2QgPSAiZ3JhcGgiLCAgZW5naW5lID0gImh0bWx3aWRnZXQiKQoKIyMgSW5kaXZpZHVhbCBSdWxlIFJlcHJlc2VudGF0aW9uIERhdGFzZXQgTGltcGlvCiMgRmlsdGVyIHRvcCAyMCBydWxlcyB3aXRoIGhpZ2hlc3QgbGlmdApzdWJSdWxlczI8LWhlYWQoc3ViUnVsZXNfZHAsIG49MjUsIGJ5PSJjb3VudCIpCnBsb3Qoc3ViUnVsZXNfZHAsIG1ldGhvZD0icGFyYWNvb3JkIikKYGBgCmBgYHtyfQojUGxvdCBTdWJSdWxlcwpwbG90KG5hcmNvdGljc19jbGVhbi5hc3NvY2lhdGlvbi5ydWxlcyxtZXRob2Q9InR3by1rZXkgcGxvdCIpCgpzdWJSdWxlc19uYXJjb3RpY3M8LW5hcmNvdGljc19jbGVhbi5hc3NvY2lhdGlvbi5ydWxlc1txdWFsaXR5KG5hcmNvdGljc19jbGVhbi5hc3NvY2lhdGlvbi5ydWxlcykkY29uZmlkZW5jZT4wLjZdCgojIyBTZWxlY2Npb25hbW9zIHVuIG51bWVybyBsaW1pdGFkbyBkZSByZWdsYXMgZW4gZWwgZGF0YXNldCBsaW1waW8KdG9wMTBzdWJSdWxlcyA8LSBoZWFkKG5hcmNvdGljc19jbGVhbi5hc3NvY2lhdGlvbi5ydWxlcywgbiA9IDEwLCBieSA9ICJjb25maWRlbmNlIikKCiMgTm93LCBwbG90IGFuIGludGVyYWN0aXZlIGdyYXBoOgojTm90ZTogWW91IGNhbiBtYWtlIGFsbCB5b3VyIHBsb3RzIGludGVyYWN0aXZlIHVzaW5nIGVuZ2luZT1odG1sd2lkZ2V0IHBhcmFtZXRlciBpbiBwbG90CnBsb3Qoc3ViUnVsZXNfbmFyY290aWNzLCBtZXRob2QgPSAiZ3JhcGgiLCAgZW5naW5lID0gImh0bWx3aWRnZXQiKQoKIyMgSW5kaXZpZHVhbCBSdWxlIFJlcHJlc2VudGF0aW9uIERhdGFzZXQgTGltcGlvCiMgRmlsdGVyIHRvcCAyMCBydWxlcyB3aXRoIGhpZ2hlc3QgbGlmdApzdWJSdWxlczI8LWhlYWQoc3ViUnVsZXNfbmFyY290aWNzLCBuPTI1LCBieT0iY29uZmlkZW5jZSIpCnBsb3Qoc3ViUnVsZXNfbmFyY290aWNzLCBtZXRob2Q9InBhcmFjb29yZCIpCmBgYApgYGB7cn0KI1Bsb3QgU3ViUnVsZXMKcGxvdChyb2JiZXJ5LmFzc29jaWF0aW9uLnJ1bGVzLG1ldGhvZD0idHdvLWtleSBwbG90IikKCnN1YlJ1bGVzX3JvYmJlcnk8LXJvYmJlcnkuYXNzb2NpYXRpb24ucnVsZXNbcXVhbGl0eShyb2JiZXJ5LmFzc29jaWF0aW9uLnJ1bGVzKSRjb25maWRlbmNlPjAuMTVdCgojIyBTZWxlY2Npb25hbW9zIHVuIG51bWVybyBsaW1pdGFkbyBkZSByZWdsYXMgZW4gZWwgZGF0YXNldCBsaW1waW8KdG9wMTBzdWJSdWxlcyA8LSBoZWFkKHJvYmJlcnkuYXNzb2NpYXRpb24ucnVsZXMsIG4gPSAxMCwgYnkgPSAiY29uZmlkZW5jZSIpCmluc3BlY3QodG9wMTBzdWJSdWxlcykKIyBOb3csIHBsb3QgYW4gaW50ZXJhY3RpdmUgZ3JhcGg6CiNOb3RlOiBZb3UgY2FuIG1ha2UgYWxsIHlvdXIgcGxvdHMgaW50ZXJhY3RpdmUgdXNpbmcgZW5naW5lPWh0bWx3aWRnZXQgcGFyYW1ldGVyIGluIHBsb3QKcGxvdChzdWJSdWxlc19yb2JiZXJ5LCBtZXRob2QgPSAiZ3JhcGgiLCAgZW5naW5lID0gImh0bWx3aWRnZXQiKQoKIyMgSW5kaXZpZHVhbCBSdWxlIFJlcHJlc2VudGF0aW9uIERhdGFzZXQgTGltcGlvCiMgRmlsdGVyIHRvcCAyMCBydWxlcyB3aXRoIGhpZ2hlc3QgbGlmdApzdWJSdWxlczI8LWhlYWQoc3ViUnVsZXNfcm9iYmVyeSwgbj0yNSwgYnk9ImNvbmZpZGVuY2UiKQpwbG90KHRvcDEwc3ViUnVsZXMsIG1ldGhvZD0icGFyYWNvb3JkIikKYGBgCmBgYHtyfQojUGxvdCBTdWJSdWxlcwpwbG90KHRoZWZ0LmFzc29jaWF0aW9uLnJ1bGVzLG1ldGhvZD0idHdvLWtleSBwbG90IikKCnN1YlJ1bGVzX3RoZWZ0PC10aGVmdC5hc3NvY2lhdGlvbi5ydWxlc1txdWFsaXR5KHRoZWZ0LmFzc29jaWF0aW9uLnJ1bGVzKSRjb25maWRlbmNlPjAuNDVdCgojIyBTZWxlY2Npb25hbW9zIHVuIG51bWVybyBsaW1pdGFkbyBkZSByZWdsYXMgZW4gZWwgZGF0YXNldCBsaW1waW8KdG9wMTBzdWJSdWxlcyA8LSBoZWFkKHRoZWZ0LmFzc29jaWF0aW9uLnJ1bGVzLCBuID0gMTAsIGJ5ID0gImNvbmZpZGVuY2UiKQppbnNwZWN0KHRvcDEwc3ViUnVsZXMpCiMgTm93LCBwbG90IGFuIGludGVyYWN0aXZlIGdyYXBoOgojTm90ZTogWW91IGNhbiBtYWtlIGFsbCB5b3VyIHBsb3RzIGludGVyYWN0aXZlIHVzaW5nIGVuZ2luZT1odG1sd2lkZ2V0IHBhcmFtZXRlciBpbiBwbG90CnBsb3Qoc3ViUnVsZXNfdGhlZnQsIG1ldGhvZCA9ICJncmFwaCIsICBlbmdpbmUgPSAiaHRtbHdpZGdldCIpCgojIyBJbmRpdmlkdWFsIFJ1bGUgUmVwcmVzZW50YXRpb24KcGxvdCh0b3AxMHN1YlJ1bGVzLCBtZXRob2Q9InBhcmFjb29yZCIpCmBgYApgYGB7cn0KI1Bsb3QgU3ViUnVsZXMKcGxvdCh2Yy5hc3NvY2lhdGlvbi5ydWxlcyxtZXRob2Q9InR3by1rZXkgcGxvdCIpCgpzdWJSdWxlc192YzwtdmMuYXNzb2NpYXRpb24ucnVsZXNbcXVhbGl0eSh2Yy5hc3NvY2lhdGlvbi5ydWxlcykkY29uZmlkZW5jZT4wLjE1XQoKIyMgU2VsZWNjaW9uYW1vcyB1biBudW1lcm8gbGltaXRhZG8gZGUgcmVnbGFzIGVuIGVsIGRhdGFzZXQgbGltcGlvCnRvcDEwc3ViUnVsZXMgPC0gaGVhZCh2Yy5hc3NvY2lhdGlvbi5ydWxlcywgbiA9IDEwLCBieSA9ICJjb25maWRlbmNlIikKaW5zcGVjdCh0b3AxMHN1YlJ1bGVzKQojIE5vdywgcGxvdCBhbiBpbnRlcmFjdGl2ZSBncmFwaDoKI05vdGU6IFlvdSBjYW4gbWFrZSBhbGwgeW91ciBwbG90cyBpbnRlcmFjdGl2ZSB1c2luZyBlbmdpbmU9aHRtbHdpZGdldCBwYXJhbWV0ZXIgaW4gcGxvdApwbG90KHN1YlJ1bGVzX3ZjLCBtZXRob2QgPSAiZ3JhcGgiLCAgZW5naW5lID0gImh0bWx3aWRnZXQiKQoKIyMgSW5kaXZpZHVhbCBSdWxlIFJlcHJlc2VudGF0aW9uCnBsb3QodG9wMTBzdWJSdWxlcywgbWV0aG9kPSJwYXJhY29vcmQiKQpgYGAKYGBge3J9CiNQbG90IFN1YlJ1bGVzCnBsb3Qod3YuYXNzb2NpYXRpb24ucnVsZXMsbWV0aG9kPSJ0d28ta2V5IHBsb3QiKQoKc3ViUnVsZXNfd3Y8LXd2LmFzc29jaWF0aW9uLnJ1bGVzW3F1YWxpdHkod3YuYXNzb2NpYXRpb24ucnVsZXMpJGNvbmZpZGVuY2U+MC4xXQoKIyMgU2VsZWNjaW9uYW1vcyB1biBudW1lcm8gbGltaXRhZG8gZGUgcmVnbGFzIGVuIGVsIGRhdGFzZXQgbGltcGlvCnRvcDEwc3ViUnVsZXMgPC0gaGVhZCh3di5hc3NvY2lhdGlvbi5ydWxlcywgbiA9IDEwLCBieSA9ICJjb25maWRlbmNlIikKaW5zcGVjdCh0b3AxMHN1YlJ1bGVzKQojIE5vdywgcGxvdCBhbiBpbnRlcmFjdGl2ZSBncmFwaDoKI05vdGU6IFlvdSBjYW4gbWFrZSBhbGwgeW91ciBwbG90cyBpbnRlcmFjdGl2ZSB1c2luZyBlbmdpbmU9aHRtbHdpZGdldCBwYXJhbWV0ZXIgaW4gcGxvdApwbG90KHN1YlJ1bGVzX3d2LCBtZXRob2QgPSAiZ3JhcGgiLCAgZW5naW5lID0gImh0bWx3aWRnZXQiKQoKIyMgSW5kaXZpZHVhbCBSdWxlIFJlcHJlc2VudGF0aW9uCnBsb3QodG9wMTBzdWJSdWxlcywgbWV0aG9kPSJwYXJhY29vcmQiKQpgYGAKCmBgYHtyfQojUGxvdCBTdWJSdWxlcwpwbG90KG9jaG8uYXNzb2NpYXRpb24ucnVsZXMsbWV0aG9kPSJ0d28ta2V5IHBsb3QiKQoKc3ViUnVsZXNfODwtb2Noby5hc3NvY2lhdGlvbi5ydWxlc1txdWFsaXR5KG9jaG8uYXNzb2NpYXRpb24ucnVsZXMpJGNvbmZpZGVuY2U+MC4wMV0KCiMjIFNlbGVjY2lvbmFtb3MgdW4gbnVtZXJvIGxpbWl0YWRvIGRlIHJlZ2xhcyBlbiBlbCBkYXRhc2V0IGxpbXBpbwp0b3AxMHN1YlJ1bGVzIDwtIGhlYWQob2Noby5hc3NvY2lhdGlvbi5ydWxlcywgbiA9IDIwLCBieSA9ICJjb25maWRlbmNlIikKaW5zcGVjdCh0b3AxMHN1YlJ1bGVzKQojIE5vdywgcGxvdCBhbiBpbnRlcmFjdGl2ZSBncmFwaDoKI05vdGU6IFlvdSBjYW4gbWFrZSBhbGwgeW91ciBwbG90cyBpbnRlcmFjdGl2ZSB1c2luZyBlbmdpbmU9aHRtbHdpZGdldCBwYXJhbWV0ZXIgaW4gcGxvdApwbG90KHN1YlJ1bGVzXzgsIG1ldGhvZCA9ICJncmFwaCIsICBlbmdpbmUgPSAiaHRtbHdpZGdldCIpCgojIyBJbmRpdmlkdWFsIFJ1bGUgUmVwcmVzZW50YXRpb24KcGxvdCh0b3AxMHN1YlJ1bGVzLCBtZXRob2Q9InBhcmFjb29yZCIpCmBgYAoKIyMgTWFwYXMgZGUgRGVuc2lkYWQKCmBgYHtyfQojIyBJTklUSUFMSVpFCmxpYnJhcnkoImxlYWZsZXQiKQpsaWJyYXJ5KCJkYXRhLnRhYmxlIikKbGlicmFyeSgic3AiKQpsaWJyYXJ5KCJyZ2RhbCIpCiMgbGlicmFyeSgibWFwdG9vbHMiKQpsaWJyYXJ5KCJLZXJuU21vb3RoIikKbGlicmFyeSh2aXJpZGlzKQpsaWJyYXJ5KFJDb2xvckJyZXdlcikKCmFzc2F1bHQgPC0gbmEub21pdChhc3NhdWx0KQpzZXREVChhc3NhdWx0KQpjcmltaW5hbF9kYW1hZ2UgPC0gbmEub21pdChjcmltaW5hbF9kYW1hZ2UpCnNldERUKGNyaW1pbmFsX2RhbWFnZSkKZGVjZXB0aXZlX3ByYWN0aWNlIDwtIG5hLm9taXQoZGVjZXB0aXZlX3ByYWN0aWNlKQpzZXREVChkZWNlcHRpdmVfcHJhY3RpY2UpCm5hcmNvdGljcyA8LSBuYS5vbWl0KG5hcmNvdGljcykKc2V0RFQobmFyY290aWNzKQpyb2JiZXJ5IDwtIG5hLm9taXQocm9iYmVyeSkKc2V0RFQocm9iYmVyeSkKdGhlZnQgPC0gbmEub21pdCh0aGVmdCkKc2V0RFQodGhlZnQpCnZpb2xlbnRfY3JpbWUgPC0gbmEub21pdCh2aW9sZW50X2NyaW1lKQpzZXREVCh2aW9sZW50X2NyaW1lKQp3ZWFwb25zX3Zpb2xhdGlvbiA8LSBuYS5vbWl0KHdlYXBvbnNfdmlvbGF0aW9uKQpzZXREVCh3ZWFwb25zX3Zpb2xhdGlvbikKCiMjIE1BS0UgQ09OVE9VUiBMSU5FUwojIyBBc3NhdWx0CmtkZV9hc3NhdWx0IDwtIGJrZGUyRChhc3NhdWx0WyAsIGxpc3QobG9uZ2l0dWRlLCBsYXRpdHVkZSldLAogICAgICAgICAgICAgIGJhbmR3aWR0aD1jKC4wMDAxLCAuMDAwMSksIGdyaWRzaXplID0gYyg3NSw3NSkpCkNMX2Fzc2F1bHQgPC0gY29udG91ckxpbmVzKGtkZV9hc3NhdWx0JHgxICwga2RlX2Fzc2F1bHQkeDIgLCBrZGVfYXNzYXVsdCRmaGF0KQoKIyMgRVhUUkFDVCBDT05UT1VSIExJTkUgTEVWRUxTCkxFVlNfYXNzYXVsdDwtIGFzLmZhY3RvcihzYXBwbHkoQ0xfYXNzYXVsdCwgYFtbYCwgImxldmVsIikpCk5MRVZfYXNzYXVsdCA8LSBsZW5ndGgobGV2ZWxzKExFVlNfYXNzYXVsdCkpCgojIyBDT05WRVJUIENPTlRPVVIgTElORVMgVE8gUE9MWUdPTlMKcGdvbnNfYXNzYXVsdCA8LSBsYXBwbHkoMTpsZW5ndGgoQ0xfYXNzYXVsdCksIGZ1bmN0aW9uKGkpCiAgICBQb2x5Z29ucyhsaXN0KFBvbHlnb24oY2JpbmQoQ0xfYXNzYXVsdFtbaV1dJHgsIENMX2Fzc2F1bHRbW2ldXSR5KSkpLCBJRD1pKSkKc3Bnb25zX2Fzc2F1bHQgPSBTcGF0aWFsUG9seWdvbnMocGdvbnNfYXNzYXVsdCkKCiMjIENyaW1pbmFsIERhbWFnZQprZGVfY2QgPC0gYmtkZTJEKGNyaW1pbmFsX2RhbWFnZVsgLCBsaXN0KGxvbmdpdHVkZSwgbGF0aXR1ZGUpXSwKICAgICAgICAgICAgICBiYW5kd2lkdGg9YyguMDAwMSwgLjAwMDEpLCBncmlkc2l6ZSA9IGMoNzUsNzUpKQpDTF9jZCA8LSBjb250b3VyTGluZXMoa2RlX2NkJHgxICwga2RlX2NkJHgyICwga2RlX2NkJGZoYXQpCgojIyBFWFRSQUNUIENPTlRPVVIgTElORSBMRVZFTFMKTEVWU19jZDwtIGFzLmZhY3RvcihzYXBwbHkoQ0xfY2QsIGBbW2AsICJsZXZlbCIpKQpOTEVWX2NkIDwtIGxlbmd0aChsZXZlbHMoTEVWU19jZCkpCgojIyBDT05WRVJUIENPTlRPVVIgTElORVMgVE8gUE9MWUdPTlMKcGdvbnNfY2QgPC0gbGFwcGx5KDE6bGVuZ3RoKENMX2NkKSwgZnVuY3Rpb24oaSkKICAgIFBvbHlnb25zKGxpc3QoUG9seWdvbihjYmluZChDTF9jZFtbaV1dJHgsIENMX2NkW1tpXV0keSkpKSwgSUQ9aSkpCnNwZ29uc19jZCA9IFNwYXRpYWxQb2x5Z29ucyhwZ29uc19jZCkKCiMjIERlY2VwdGl2ZSBQcmFjdGljZQprZGVfZHAgPC0gYmtkZTJEKGRlY2VwdGl2ZV9wcmFjdGljZVsgLCBsaXN0KGxvbmdpdHVkZSwgbGF0aXR1ZGUpXSwKICAgICAgICAgICAgICBiYW5kd2lkdGg9YyguMDAwMSwgLjAwMDEpLCBncmlkc2l6ZSA9IGMoNzUsNzUpKQpDTF9kcCA8LSBjb250b3VyTGluZXMoa2RlX2RwJHgxICwga2RlX2RwJHgyICwga2RlX2RwJGZoYXQpCgojIyBFWFRSQUNUIENPTlRPVVIgTElORSBMRVZFTFMKTEVWU19kcDwtIGFzLmZhY3RvcihzYXBwbHkoQ0xfZHAsIGBbW2AsICJsZXZlbCIpKQpOTEVWX2RwIDwtIGxlbmd0aChsZXZlbHMoTEVWU19kcCkpCgojIyBDT05WRVJUIENPTlRPVVIgTElORVMgVE8gUE9MWUdPTlMKcGdvbnNfZHAgPC0gbGFwcGx5KDE6bGVuZ3RoKENMX2RwKSwgZnVuY3Rpb24oaSkKICAgIFBvbHlnb25zKGxpc3QoUG9seWdvbihjYmluZChDTF9kcFtbaV1dJHgsIENMX2RwW1tpXV0keSkpKSwgSUQ9aSkpCnNwZ29uc19kcCA9IFNwYXRpYWxQb2x5Z29ucyhwZ29uc19kcCkKCiMjIE5hcmNvdGljcwprZGVfbmFyY290aWNzIDwtIGJrZGUyRChuYXJjb3RpY3NbICwgbGlzdChsb25naXR1ZGUsIGxhdGl0dWRlKV0sCiAgICAgICAgICAgICAgYmFuZHdpZHRoPWMoLjAwMDEsIC4wMDAxKSwgZ3JpZHNpemUgPSBjKDc1LDc1KSkKQ0xfbmFyY290aWNzIDwtIGNvbnRvdXJMaW5lcyhrZGVfbmFyY290aWNzJHgxICwga2RlX25hcmNvdGljcyR4MiAsIGtkZV9uYXJjb3RpY3MkZmhhdCkKCiMjIEVYVFJBQ1QgQ09OVE9VUiBMSU5FIExFVkVMUwpMRVZTX25hcmNvdGljcyA8LSBhcy5mYWN0b3Ioc2FwcGx5KENMX25hcmNvdGljcywgYFtbYCwgImxldmVsIikpCk5MRVZfbmFyY290aWNzIDwtIGxlbmd0aChsZXZlbHMoTEVWU19uYXJjb3RpY3MpKQoKIyMgQ09OVkVSVCBDT05UT1VSIExJTkVTIFRPIFBPTFlHT05TCnBnb25zX25hcmNvdGljcyA8LSBsYXBwbHkoMTpsZW5ndGgoQ0xfbmFyY290aWNzKSwgZnVuY3Rpb24oaSkKICAgIFBvbHlnb25zKGxpc3QoUG9seWdvbihjYmluZChDTF9uYXJjb3RpY3NbW2ldXSR4LCBDTF9uYXJjb3RpY3NbW2ldXSR5KSkpLCBJRD1pKSkKc3Bnb25zX25hcmNvdGljcyA9IFNwYXRpYWxQb2x5Z29ucyhwZ29uc19uYXJjb3RpY3MpCgojIyBSb2JiZXJ5CmtkZV9yb2JiZXJ5IDwtIGJrZGUyRChyb2JiZXJ5WyAsIGxpc3QobG9uZ2l0dWRlLCBsYXRpdHVkZSldLAogICAgICAgICAgICAgIGJhbmR3aWR0aD1jKC4wMDAxLCAuMDAwMSksIGdyaWRzaXplID0gYyg3NSw3NSkpCkNMX3JvYmJlcnkgPC0gY29udG91ckxpbmVzKGtkZV9yb2JiZXJ5JHgxICwga2RlX3JvYmJlcnkkeDIgLCBrZGVfcm9iYmVyeSRmaGF0KQoKIyMgRVhUUkFDVCBDT05UT1VSIExJTkUgTEVWRUxTCkxFVlNfcm9iYmVyeSA8LSBhcy5mYWN0b3Ioc2FwcGx5KENMX3JvYmJlcnksIGBbW2AsICJsZXZlbCIpKQpOTEVWX3JvYmJlcnkgPC0gbGVuZ3RoKGxldmVscyhMRVZTX3JvYmJlcnkpKQoKIyMgQ09OVkVSVCBDT05UT1VSIExJTkVTIFRPIFBPTFlHT05TCnBnb25zX3JvYmJlcnkgPC0gbGFwcGx5KDE6bGVuZ3RoKENMX3JvYmJlcnkpLCBmdW5jdGlvbihpKQogICAgUG9seWdvbnMobGlzdChQb2x5Z29uKGNiaW5kKENMX3JvYmJlcnlbW2ldXSR4LCBDTF9yb2JiZXJ5W1tpXV0keSkpKSwgSUQ9aSkpCnNwZ29uc19yb2JiZXJ5ID0gU3BhdGlhbFBvbHlnb25zKHBnb25zX3JvYmJlcnkpCgojIyBUaGVmdHMKa2RlX3RoZWZ0IDwtIGJrZGUyRCh0aGVmdFsgLCBsaXN0KGxvbmdpdHVkZSwgbGF0aXR1ZGUpXSwKICAgICAgICAgICAgICBiYW5kd2lkdGg9YyguMDAwMSwgLjAwMDEpLCBncmlkc2l6ZSA9IGMoNzUsNzUpKQpDTF90aGVmdCA8LSBjb250b3VyTGluZXMoa2RlX3RoZWZ0JHgxICwga2RlX3RoZWZ0JHgyICwga2RlX3RoZWZ0JGZoYXQpCgojIyBFWFRSQUNUIENPTlRPVVIgTElORSBMRVZFTFMKTEVWU190aGVmdCA8LSBhcy5mYWN0b3Ioc2FwcGx5KENMX3RoZWZ0LCBgW1tgLCAibGV2ZWwiKSkKTkxFVl90aGVmdCA8LSBsZW5ndGgobGV2ZWxzKExFVlNfdGhlZnQpKQoKIyMgQ09OVkVSVCBDT05UT1VSIExJTkVTIFRPIFBPTFlHT05TCnBnb25zX3RoZWZ0IDwtIGxhcHBseSgxOmxlbmd0aChDTF90aGVmdCksIGZ1bmN0aW9uKGkpCiAgICBQb2x5Z29ucyhsaXN0KFBvbHlnb24oY2JpbmQoQ0xfdGhlZnRbW2ldXSR4LCBDTF90aGVmdFtbaV1dJHkpKSksIElEPWkpKQpzcGdvbnNfdGhlZnQgPSBTcGF0aWFsUG9seWdvbnMocGdvbnNfdGhlZnQpCgojIyBWaW9sZW50IENyaW13cwprZGVfdmMgPC0gYmtkZTJEKHZpb2xlbnRfY3JpbWVbICwgbGlzdChsb25naXR1ZGUsIGxhdGl0dWRlKV0sCiAgICAgICAgICAgICAgYmFuZHdpZHRoPWMoLjAwMDEsIC4wMDAxKSwgZ3JpZHNpemUgPSBjKDc1LDc1KSkKQ0xfdmMgPC0gY29udG91ckxpbmVzKGtkZV92YyR4MSAsIGtkZV92YyR4MiAsIGtkZV92YyRmaGF0KQoKIyMgRVhUUkFDVCBDT05UT1VSIExJTkUgTEVWRUxTCkxFVlNfdmMgPC0gYXMuZmFjdG9yKHNhcHBseShDTF92YywgYFtbYCwgImxldmVsIikpCk5MRVZfdmMgPC0gbGVuZ3RoKGxldmVscyhMRVZTX3ZjKSkKCiMjIENPTlZFUlQgQ09OVE9VUiBMSU5FUyBUTyBQT0xZR09OUwpwZ29uc192YyA8LSBsYXBwbHkoMTpsZW5ndGgoQ0xfdmMpLCBmdW5jdGlvbihpKQogICAgUG9seWdvbnMobGlzdChQb2x5Z29uKGNiaW5kKENMX3ZjW1tpXV0keCwgQ0xfdmNbW2ldXSR5KSkpLCBJRD1pKSkKc3Bnb25zX3ZjID0gU3BhdGlhbFBvbHlnb25zKHBnb25zX3ZjKQoKIyMgV2VhcG9ucyBWaW9sYXRpb24Ka2RlX3d2IDwtIGJrZGUyRCh3ZWFwb25zX3Zpb2xhdGlvblsgLCBsaXN0KGxvbmdpdHVkZSwgbGF0aXR1ZGUpXSwKICAgICAgICAgICAgICBiYW5kd2lkdGg9YyguMDAwMSwgLjAwMDEpLCBncmlkc2l6ZSA9IGMoNzUsNzUpKQpDTF93diA8LSBjb250b3VyTGluZXMoa2RlX3d2JHgxICwga2RlX3d2JHgyICwga2RlX3d2JGZoYXQpCgojIyBFWFRSQUNUIENPTlRPVVIgTElORSBMRVZFTFMKTEVWU193diA8LSBhcy5mYWN0b3Ioc2FwcGx5KENMX3d2LCBgW1tgLCAibGV2ZWwiKSkKTkxFVl93diA8LSBsZW5ndGgobGV2ZWxzKExFVlNfd3YpKQoKIyMgQ09OVkVSVCBDT05UT1VSIExJTkVTIFRPIFBPTFlHT05TCnBnb25zX3d2IDwtIGxhcHBseSgxOmxlbmd0aChDTF93diksIGZ1bmN0aW9uKGkpCiAgICBQb2x5Z29ucyhsaXN0KFBvbHlnb24oY2JpbmQoQ0xfd3ZbW2ldXSR4LCBDTF93dltbaV1dJHkpKSksIElEPWkpKQpzcGdvbnNfd3YgPSBTcGF0aWFsUG9seWdvbnMocGdvbnNfd3YpCgpsZWFmbGV0KCkgJT4lIGFkZFRpbGVzKCkgJT4lCiAgICBhZGRQb2x5Z29ucyhkYXRhID0gc3Bnb25zX25hcmNvdGljcywgY29sb3IgPSBicmV3ZXIucGFsKE5MRVZfbmFyY290aWNzLCBuYW1lID0gIllsT3JSZCIpW0xFVlNfbmFyY290aWNzXSwgZ3JvdXAgPSAiTmFyY290aWNzIikgJT4lCiAgICBhZGRQb2x5Z29ucyhkYXRhID0gc3Bnb25zX2Fzc2F1bHQsIGNvbG9yID0gYnJld2VyLnBhbChOTEVWX2Fzc2F1bHQsIG5hbWUgPSAiUmVkcyIpW0xFVlNfYXNzYXVsdF0sIGdyb3VwID0gIkFzc2F1bHQiKSAlPiUKICAgIGFkZFBvbHlnb25zKGRhdGEgPSBzcGdvbnNfY2QsIGNvbG9yID0gYnJld2VyLnBhbChOTEVWX2NkLCBuYW1lPSJZbEduQnUiKVtMRVZTX2NkXSwgZ3JvdXAgPSAiQ3JpbWluYWwgRGFtYWdlIikgJT4lCiAgICBhZGRQb2x5Z29ucyhkYXRhID0gc3Bnb25zX2RwLCBjb2xvciA9IGJyZXdlci5wYWwoTkxFVl9kcCwgbmFtZSA9ICJZbEduIilbTEVWU19kcF0sIGdyb3VwID0gIkRlY2VwdGl2ZSBQcmFjdGljZSIpICU+JQogICAgYWRkUG9seWdvbnMoZGF0YSA9IHNwZ29uc19yb2JiZXJ5LCBjb2xvciA9IGJyZXdlci5wYWwoTkxFVl9yb2JiZXJ5LCBuYW1lID0gIlB1cnBsZXMiKVtMRVZTX3JvYmJlcnldLCBncm91cCA9ICJSb2JiZXJ5IikgJT4lCiAgICBhZGRQb2x5Z29ucyhkYXRhID0gc3Bnb25zX3RoZWZ0LCBjb2xvciA9IGJyZXdlci5wYWwoTkxFVl90aGVmdCwgbmFtZSA9ICJPcmFuZ2VzIilbTEVWU190aGVmdF0sIGdyb3VwID0gIlRoZWZ0cyIpICU+JQogICAgYWRkUG9seWdvbnMoZGF0YSA9IHNwZ29uc192YywgY29sb3IgPSBicmV3ZXIucGFsKE5MRVZfdmMsIG5hbWUgPSAiR3JleXMiKVtMRVZTX3ZjXSwgZ3JvdXAgPSAiVmlvbGVudCBDcmltZXMiKSAlPiUKICAgIGFkZFBvbHlnb25zKGRhdGEgPSBzcGdvbnNfd3YsIGNvbG9yID0gYnJld2VyLnBhbChOTEVWX3d2LCBuYW1lID0gIkJsdWVzIilbTEVWU193dl0sIGdyb3VwID0gIldlYXBvbnMgVmlvbGF0aW9uIikgJT4lCiAgICBhZGRMYWJlbE9ubHlNYXJrZXJzKGRpc3RyaWN0cyRsb25naXR1ZGUsIGRpc3RyaWN0cyRsYXRpdHVkZSwgbGFiZWwgPSAgZGlzdHJpY3RzJGRpc3RyaWN0LCAKICAgICAgICAgICAgICAgICAgICAgIGxhYmVsT3B0aW9ucyA9IGxhYmVsT3B0aW9ucyhub0hpZGUgPSBULCBkaXJlY3Rpb24gPSAndG9wJywgdGV4dE9ubHkgPSBUKSwgZ3JvdXAgPSAiRGlzdHJpY3RzIikgJT4lCiAgICBhZGRMYXllcnNDb250cm9sKG92ZXJsYXlHcm91cHMgPSBjKCJBc3NhdWx0IiwgIkNyaW1pbmFsIERhbWFnZSIsIkRlY2VwdGl2ZSBQcmFjdGljZSIsICJOYXJjb3RpY3MiLCJSb2JiZXJ5IiwiVGhlZnRzIiwiVmlvbGVudCBDcmltZXMiLCJXZWFwb25zIFZpb2xhdGlvbiIsICJEaXN0cmljdHMiKSxvcHRpb25zID0gbGF5ZXJzQ29udHJvbE9wdGlvbnMoY29sbGFwc2VkID0gRkFMU0UpKQogICAgCiNhZGRDaXJjbGVzKGxuZyA9IG5hcmNvdGljcyRsb25naXR1ZGUsIGxhdCA9IG5hcmNvdGljcyRsYXRpdHVkZSxyYWRpdXMgPSAuMSwgb3BhY2l0eSA9IC40LCBjb2wgPSAiYmx1ZSIsIGdyb3VwID0gIlBvaW50cyIpICU+JQoKCmBgYApgYGB7cn0KI2xlYWZsZXQoKSAlPiUgYWRkVGlsZXMoKSAlPiUKIyAgICBhZGRDaXJjbGVzKGxuZyA9IHdlYXBvbnNfdmlvbGF0aW9uJGxvbmdpdHVkZSwgbGF0ID0gd2VhcG9uc192aW9sYXRpb24kbGF0aXR1ZGUscmFkaXVzID0gLjA1LCBvcGFjaXR5ID0gMC4xLCBjb2wgPSBicmV3ZXIucGFsKDEwLG5hbWUgPSAiUmVkcyIpLCBncm91cCA9ICJOYXJjb3RpY3MiKSAlPiUKIyAgICBhZGRMYWJlbE9ubHlNYXJrZXJzKGRpc3RyaWN0cyRsb25naXR1ZGUsIGRpc3RyaWN0cyRsYXRpdHVkZSwgbGFiZWwgPSAgZGlzdHJpY3RzJGRpc3RyaWN0LCAKIyAgICAgICAgICAgICAgICAgICAgICBsYWJlbE9wdGlvbnMgPSBsYWJlbE9wdGlvbnMobm9IaWRlID0gVCwgZGlyZWN0aW9uID0gJ3RvcCcsIHRleHRPbmx5ID0gVCwgdGV4dHNpemUgPSAiMTVweCIpLCBncm91cCA9ICMiRGlzdHJpY3RzIikgJT4lCiMgICAgYWRkTGF5ZXJzQ29udHJvbChvdmVybGF5R3JvdXBzID0gYygiQXNzYXVsdCIsICJDcmltaW5hbCBEYW1hZ2UiLCJEZWNlcHRpdmUgUHJhY3RpY2UiLCAiTmFyY290aWNzIiwiUm9iYmVyeSIsIlRoZWZ0cyIsIlZpb2xlbnQgQ3JpbWVzIiwiV2VhcG9ucyBWaW9sYXRpb24iLCAiRGlzdHJpY3RzIiksb3B0aW9ucyA9IGxheWVyc0NvbnRyb2xPcHRpb25zKGNvbGxhcHNlZCA9IEZBTFNFKSkKCmBgYAojIyBDbHVzdGVyaW5nIApgYGB7cn0KY2hpY2Fnb19jcmltZV9jbHVzdGVyaW5nIDwtIHN1YnNldChjaGljYWdvX2NyaW1lX3N1YnNldCwgc2VsZWN0PS1jKGxvY2F0aW9uX2Rlc2NyaXB0aW9uLGNhc2VfbnVtYmVyLGJsb2NrLHdhcmQsZGVzY3JpcHRpb24sZGF5LG1vbnRoLGxhdGl0dWRlLGxvbmdpdHVkZSkpCnVuaXF1ZShjaGljYWdvX2NyaW1lX2NsdXN0ZXJpbmckcHJpbWFyeV90eXBlKQoKbGlicmFyeShkYXRhLnRhYmxlKQpsaWJyYXJ5KG1sdG9vbHMpCiNDcmltZV9jaGljYWdvX2R1bW15IDwtIG9uZV9ob3QoYXMuZGF0YS50YWJsZShDcmltZV9jaGljYWdvX2RlZl9jbHVzdCkpCgp0eXBlcyA8LSB1bmlxdWUoY2hpY2Fnb19jcmltZV9jbHVzdGVyaW5nJHByaW1hcnlfdHlwZSkKY2hpY2Fnb19jcmltZV9jbHVzdGVyaW5nJHByaW1hcnlfdHlwZSA8LSBtYXRjaChjaGljYWdvX2NyaW1lX2NsdXN0ZXJpbmckcHJpbWFyeV90eXBlLCB1bmlxdWUoY2hpY2Fnb19jcmltZV9jbHVzdGVyaW5nJHByaW1hcnlfdHlwZSkpCmNoaWNhZ29fY3JpbWVfY2x1c3RlcmluZyRhcnJlc3QgPC0gbWF0Y2goY2hpY2Fnb19jcmltZV9jbHVzdGVyaW5nJGFycmVzdCwgdW5pcXVlKGNoaWNhZ29fY3JpbWVfY2x1c3RlcmluZyRhcnJlc3QpKQojY2hpY2Fnb19jcmltZV9jbHVzdGVyaW5nJGxvY2F0aW9uX2Rlc2NyaXB0aW9uIDwtIG1hdGNoKGNoaWNhZ29fY3JpbWVfY2x1c3RlcmluZyRsb2NhdGlvbl9kZXNjcmlwdGlvbiwgdW5pcXVlKGNoaWNhZ29fY3JpbWVfY2x1c3RlcmluZyRsb2NhdGlvbl9kZXNjcmlwdGlvbikpCmNoaWNhZ29fY3JpbWVfY2x1c3RlcmluZyRkaXN0cmljdCA8LSBhcy5udW1lcmljKGNoaWNhZ29fY3JpbWVfY2x1c3RlcmluZyRkaXN0cmljdCkKdGVzdCA8LSBjaGljYWdvX2NyaW1lX2NsdXN0ZXJpbmcKI05vcm1hbGl6YXRpb24gb2YgdmFyaWFibGVzCmxpYnJhcnkoUlNOTlMpCgp0cmFpbl9zZXQgPC0gc3Vic2V0KGNoaWNhZ29fY3JpbWVfc3Vic2V0X3RyLCBzZWxlY3Q9LWMobG9jYXRpb25fZGVzY3JpcHRpb24sY2FzZV9udW1iZXIsYmxvY2ssd2FyZCxkZXNjcmlwdGlvbixkYXksbW9udGgsbGF0aXR1ZGUsbG9uZ2l0dWRlKSkKdHJhaW5fc2V0JHByaW1hcnlfdHlwZSA8LSBtYXRjaCh0cmFpbl9zZXQkcHJpbWFyeV90eXBlLCB1bmlxdWUodHJhaW5fc2V0JHByaW1hcnlfdHlwZSkpCnRyYWluX3NldCRhcnJlc3QgPC0gbWF0Y2godHJhaW5fc2V0JGFycmVzdCwgdW5pcXVlKHRyYWluX3NldCRhcnJlc3QpKQojdHJhaW5fc2V0JGxvY2F0aW9uX2Rlc2NyaXB0aW9uIDwtIG1hdGNoKHRyYWluX3NldCRsb2NhdGlvbl9kZXNjcmlwdGlvbiwgdW5pcXVlKHRyYWluX3NldCRsb2NhdGlvbl9kZXNjcmlwdGlvbikpCnRyYWluX3NldCRkaXN0cmljdCA8LSBhcy5udW1lcmljKHRyYWluX3NldCRkaXN0cmljdCkKCiNpbmRleCA8LSBzYW1wbGUobnJvdyhjaGljYWdvX2NyaW1lX2NsdXN0ZXJpbmdfY3V0KSwgcm91bmQoMC43NSpucm93KGNoaWNhZ29fY3JpbWVfY2x1c3RlcmluZ19jdXQpKSkKI3RyYWluIDwtIENyaW1lX2NoaWNhZ29fZGVmX2NsdXN0X2N1dFtpbmRleCxdIAojdGVzdCA8LSBDcmltZV9jaGljYWdvX2RlZl9jbHVzdF9jdXRbLWluZGV4LF0KdHJhaW5fbGFiZWwgPC0gdHJhaW5fc2V0WywxXQp0ZXN0X2xhYmVsIDwtIHRlc3RbLDFdCgojT3B0aW11bSBudW1iZXIgb2YgY2x1c3RlcnMuIEVsYm93IG1ldGhvZAojIEFsdGVybmF0aXZlIHVzaW5nIGZ2aXogZnVuY3Rpb24gZm9yIEVsYm93IG1ldGhvZApsaWJyYXJ5KGZhY3RvZXh0cmEpCmxpYnJhcnkoTmJDbHVzdCkKc2V0LnNlZWQoMTIzKQp0cmFpbl9zbWFsbCA8LSB0cmFpbl9zZXRbMToxMDAwLF0KdGVzdF9zbWFsbCA8LSB0ZXN0WzE6MTAwLF0KCiMjIERlbmRvZ3JhbXMKbGlicmFyeSh0aWR5dmVyc2UpICAgICAgI2RhdGEgbWFuaXB1bGF0aW9uIGFuZCB2aXN1YWxpemF0aW9uCmxpYnJhcnkoY2xhc3MpICAgICAgICAgICMgdG8gY2FsbCBjbGFzcyBwYWNrYWdlIGZvciBrTk4KbGlicmFyeShjYXJldCkKbGlicmFyeShjbHVzdGVyKQojIERpdmlzaXZlIEhpZXJhcmNoaWNhbCBDbHVzdGVyaW5nIC0gZGlhbmEKIyBjb21wdXRlIGRpdmlzaXZlIGhpZXJhcmNoaWNhbCBjbHVzdGVyaW5nCmRpdiA8LSBkaWFuYSh0cmFpbl9zbWFsbCkKcGxvdChkaXYsIG1haW4gPSAiRGl2aXNpdmUiKQoKZGlzdGFuY2UgPC0gZGlzdCh0cmFpbl9zbWFsbCxtZXRob2QgPSAiZXVjbGlkZWFuIikKYWdnIDwtIGhjbHVzdChkaXN0YW5jZSwgbWV0aG9kID0gImNvbXBsZXRlIikKcGxvdChhZ2csCiAgICAgbWFpbiA9ICJBZ2dsb21lcmF0aXZlLCBjb21wbGV0ZSBsaW5rYWdlcyIpCgpsaWJyYXJ5KGZwYykKY3N0YXRzLnRhYmxlIDwtIGZ1bmN0aW9uKGRpc3QsIHRyZWUsIGspIHsKY2x1c3QuYXNzZXNzIDwtIGMoImNsdXN0ZXIubnVtYmVyIiwibiIsIndpdGhpbi5jbHVzdGVyLnNzIiwiYXZlcmFnZS53aXRoaW4iLCJhdmVyYWdlLmJldHdlZW4iLAogICAgICAgICAgICAgICAgICAid2IucmF0aW8iLCJkdW5uMiIsImF2Zy5zaWx3aWR0aCIpCmNsdXN0LnNpemUgPC0gYygiY2x1c3Rlci5zaXplIikKc3RhdHMubmFtZXMgPC0gYygpCnJvdy5jbHVzdCA8LSBjKCkKb3V0cHV0LnN0YXRzIDwtIG1hdHJpeChuY29sID0gaywgbnJvdyA9IGxlbmd0aChjbHVzdC5hc3Nlc3MpKQpjbHVzdGVyLnNpemVzIDwtIG1hdHJpeChuY29sID0gaywgbnJvdyA9IGspCmZvcihpIGluIGMoMTprKSl7CiAgcm93LmNsdXN0W2ldIDwtIHBhc3RlKCJDbHVzdGVyLSIsIGksICIgc2l6ZSIpCn0KZm9yKGkgaW4gYygyOmspKXsKICBzdGF0cy5uYW1lc1tpXSA8LSBwYXN0ZSgiVGVzdCIsIGktMSkKICAKICBmb3IoaiBpbiBzZXFfYWxvbmcoY2x1c3QuYXNzZXNzKSl7CiAgICBvdXRwdXQuc3RhdHNbaiwgaV0gPC0gdW5saXN0KGNsdXN0ZXIuc3RhdHMoZCA9IGRpc3QsIGNsdXN0ZXJpbmcgPSBjdXRyZWUodHJlZSwgayA9IGkpKVtjbHVzdC5hc3Nlc3NdKVtqXQogICAgCiAgfQogIAogIGZvcihkIGluIDE6aykgewogICAgY2x1c3Rlci5zaXplc1tkLCBpXSA8LSB1bmxpc3QoY2x1c3Rlci5zdGF0cyhkID0gZGlzdCwgY2x1c3RlcmluZyA9IGN1dHJlZSh0cmVlLCBrID0gaSkpW2NsdXN0LnNpemVdKVtkXQogICAgZGltKGNsdXN0ZXIuc2l6ZXNbZCwgaV0pIDwtIGMobGVuZ3RoKGNsdXN0ZXIuc2l6ZXNbaV0pLCAxKQogICAgY2x1c3Rlci5zaXplc1tkLCBpXQogICAgCiAgfQp9Cm91dHB1dC5zdGF0cy5kZiA8LSBkYXRhLmZyYW1lKG91dHB1dC5zdGF0cykKY2x1c3Rlci5zaXplcyA8LSBkYXRhLmZyYW1lKGNsdXN0ZXIuc2l6ZXMpCmNsdXN0ZXIuc2l6ZXNbaXMubmEoY2x1c3Rlci5zaXplcyldIDwtIDAKcm93cy5hbGwgPC0gYyhjbHVzdC5hc3Nlc3MsIHJvdy5jbHVzdCkKIyByb3duYW1lcyhvdXRwdXQuc3RhdHMuZGYpIDwtIGNsdXN0LmFzc2VzcwpvdXRwdXQgPC0gcmJpbmQob3V0cHV0LnN0YXRzLmRmLCBjbHVzdGVyLnNpemVzKVsgLC0xXQpjb2xuYW1lcyhvdXRwdXQpIDwtIHN0YXRzLm5hbWVzWzI6a10Kcm93bmFtZXMob3V0cHV0KSA8LSByb3dzLmFsbAppcy5udW0gPC0gc2FwcGx5KG91dHB1dCwgaXMubnVtZXJpYykKb3V0cHV0W2lzLm51bV0gPC0gbGFwcGx5KG91dHB1dFtpcy5udW1dLCByb3VuZCwgMikKb3V0cHV0Cn0KIyBJIGFtIGNhcHBpbmcgdGhlIG1heGltdW0gYW1vdXQgb2YgY2x1c3RlcnMgYnkgNwojIEkgd2FudCB0byBjaG9vc2UgYSByZWFzb25hYmxlIG51bWJlciwgYmFzZWQgb24gd2hpY2ggSSB3aWxsIGJlIGFibGUgdG8gc2VlIGJhc2ljIGRpZmZlcmVuY2VzIGJldHdlZW4gY3VzdG9tZXIgZ3JvdXBzIGFzIGEgcmVzdWx0CnN0YXRzLmRmLmRpdmlzaXZlIDwtIGNzdGF0cy50YWJsZShkaXN0YW5jZSwgZGl2LCA3KQpzdGF0cy5kZi5kaXZpc2l2ZQoKc3RhdHMuZGYuYWdnbCA8LWNzdGF0cy50YWJsZShkaXN0YW5jZSwgYWdnLCA3KSAjY29tcGxldGUgbGlua2FnZXMgbG9va3MgbGlrZSB0aGUgbW9zdCBiYWxhbmNlZCBhcHByb2FjaApzdGF0cy5kZi5hZ2dsCgojY29uZnVzaW9uTWF0cml4KHRyYWluX3NtYWxsLCApCmBgYApgYGB7cn0KbGlicmFyeShkYXRhLnRhYmxlKQpsaWJyYXJ5KG1sdG9vbHMpCiNDcmltZV9jaGljYWdvX2R1bW15IDwtIG9uZV9ob3QoYXMuZGF0YS50YWJsZShDcmltZV9jaGljYWdvX2RlZl9jbHVzdCkpCiNuYXJjb3RpY3MgPC0gc3Vic2V0KG5hcmNvdGljcywgc2VsZWN0PS1jKGNhc2VfbnVtYmVyLGJsb2NrLHdhcmQsZGVzY3JpcHRpb24sZGF5LG1vbnRoLGxhdGl0dWRlLGxvbmdpdHVkZSkpCiNuYXJjb3RpY3NfdHIgPC0gc3Vic2V0KG5hcmNvdGljc190ciwgc2VsZWN0PS1jKGNhc2VfbnVtYmVyLGJsb2NrLHdhcmQsZGVzY3JpcHRpb24sZGF5LG1vbnRoLGxhdGl0dWRlLGxvbmdpdHVkZSkpCm5hcmNvdGljc19jbHVzdGVyaW5nIDwtIHN1YnNldChuYXJjb3RpY3MsIHNlbGVjdD0tYyhsb2NhdGlvbl9kZXNjcmlwdGlvbikpCm5hcmNvdGljc19jbHVzdGVyaW5nX3RyIDwtIHN1YnNldChuYXJjb3RpY3NfdHIsIHNlbGVjdD0tYyhsb2NhdGlvbl9kZXNjcmlwdGlvbikpCgp0eXBlcyA8LSB1bmlxdWUoY2hpY2Fnb19jcmltZV9jbHVzdGVyaW5nJHByaW1hcnlfdHlwZSkKbmFyY290aWNzX2NsdXN0ZXJpbmckcHJpbWFyeV90eXBlIDwtIG1hdGNoKGNoaWNhZ29fY3JpbWVfY2x1c3RlcmluZyRwcmltYXJ5X3R5cGUsIHVuaXF1ZShjaGljYWdvX2NyaW1lX2NsdXN0ZXJpbmckcHJpbWFyeV90eXBlKSkKbmFyY290aWNzX2NsdXN0ZXJpbmckYXJyZXN0IDwtIG1hdGNoKGNoaWNhZ29fY3JpbWVfY2x1c3RlcmluZyRhcnJlc3QsIHVuaXF1ZShjaGljYWdvX2NyaW1lX2NsdXN0ZXJpbmckYXJyZXN0KSkKI25hcmNvdGljc19jbHVzdGVyaW5nJGxvY2F0aW9uX2Rlc2NyaXB0aW9uIDwtIG1hdGNoKGNoaWNhZ29fY3JpbWVfY2x1c3RlcmluZyRsb2NhdGlvbl9kZXNjcmlwdGlvbiwgdW5pcXVlKG5hcmNvdGljc19jbHVzdGVyaW5nJGxvY2F0aW9uX2Rlc2NyaXB0aW9uKSkKbmFyY290aWNzX2NsdXN0ZXJpbmckZGlzdHJpY3QgPC0gYXMubnVtZXJpYyhuYXJjb3RpY3NfY2x1c3RlcmluZyRkaXN0cmljdCkKdGVzdCA8LSBuYXJjb3RpY3NfY2x1c3RlcmluZwojTm9ybWFsaXphdGlvbiBvZiB2YXJpYWJsZXMKbGlicmFyeShSU05OUykKCnRyYWluX3NldCA8LSBuYXJjb3RpY3NfY2x1c3RlcmluZ190cgp0cmFpbl9zZXQkcHJpbWFyeV90eXBlIDwtIG1hdGNoKHRyYWluX3NldCRwcmltYXJ5X3R5cGUsIHVuaXF1ZSh0cmFpbl9zZXQkcHJpbWFyeV90eXBlKSkKdHJhaW5fc2V0JGFycmVzdCA8LSBtYXRjaCh0cmFpbl9zZXQkYXJyZXN0LCB1bmlxdWUodHJhaW5fc2V0JGFycmVzdCkpCiN0cmFpbl9zZXQkbG9jYXRpb25fZGVzY3JpcHRpb24gPC0gbWF0Y2godHJhaW5fc2V0JGxvY2F0aW9uX2Rlc2NyaXB0aW9uLCB1bmlxdWUodHJhaW5fc2V0JGxvY2F0aW9uX2Rlc2NyaXB0aW9uKSkKdHJhaW5fc2V0JGRpc3RyaWN0IDwtIGFzLm51bWVyaWModHJhaW5fc2V0JGRpc3RyaWN0KQoKI2luZGV4IDwtIHNhbXBsZShucm93KGNoaWNhZ29fY3JpbWVfY2x1c3RlcmluZ19jdXQpLCByb3VuZCgwLjc1Km5yb3coY2hpY2Fnb19jcmltZV9jbHVzdGVyaW5nX2N1dCkpKQojdHJhaW4gPC0gQ3JpbWVfY2hpY2Fnb19kZWZfY2x1c3RfY3V0W2luZGV4LF0gCiN0ZXN0IDwtIENyaW1lX2NoaWNhZ29fZGVmX2NsdXN0X2N1dFstaW5kZXgsXQp0cmFpbl9sYWJlbCA8LSB0cmFpbl9zZXRbLDFdCnRlc3RfbGFiZWwgPC0gdGVzdFssMV0KCiNPcHRpbXVtIG51bWJlciBvZiBjbHVzdGVycy4gRWxib3cgbWV0aG9kCiMgQWx0ZXJuYXRpdmUgdXNpbmcgZnZpeiBmdW5jdGlvbiBmb3IgRWxib3cgbWV0aG9kCmxpYnJhcnkoZmFjdG9leHRyYSkKbGlicmFyeShOYkNsdXN0KQpzZXQuc2VlZCgxMjMpCnRyYWluX3NtYWxsIDwtIHRyYWluX3NldFsxOjEwMDAsXQp0ZXN0X3NtYWxsIDwtIHRlc3RbMToxMDAsXQoKIyMgRGVuZG9ncmFtcwpsaWJyYXJ5KHRpZHl2ZXJzZSkgICAgICAjZGF0YSBtYW5pcHVsYXRpb24gYW5kIHZpc3VhbGl6YXRpb24KbGlicmFyeShjbGFzcykgICAgICAgICAgIyB0byBjYWxsIGNsYXNzIHBhY2thZ2UgZm9yIGtOTgpsaWJyYXJ5KGNhcmV0KQpsaWJyYXJ5KGNsdXN0ZXIpCiMgRGl2aXNpdmUgSGllcmFyY2hpY2FsIENsdXN0ZXJpbmcgLSBkaWFuYQojIGNvbXB1dGUgZGl2aXNpdmUgaGllcmFyY2hpY2FsIGNsdXN0ZXJpbmcKZGl2IDwtIGRpYW5hKHRyYWluX3NtYWxsKQpwbG90KGRpdiwgbWFpbiA9ICJEaXZpc2l2ZSIpCgpkaXN0YW5jZSA8LSBkaXN0KHRyYWluX3NtYWxsLG1ldGhvZCA9ICJldWNsaWRlYW4iKQphZ2cgPC0gaGNsdXN0KGRpc3RhbmNlLCBtZXRob2QgPSAiY29tcGxldGUiKQpwbG90KGFnZywKICAgICBtYWluID0gIkFnZ2xvbWVyYXRpdmUsIGNvbXBsZXRlIGxpbmthZ2VzIikKCmxpYnJhcnkoZnBjKQpjc3RhdHMudGFibGUgPC0gZnVuY3Rpb24oZGlzdCwgdHJlZSwgaykgewpjbHVzdC5hc3Nlc3MgPC0gYygiY2x1c3Rlci5udW1iZXIiLCJuIiwid2l0aGluLmNsdXN0ZXIuc3MiLCJhdmVyYWdlLndpdGhpbiIsImF2ZXJhZ2UuYmV0d2VlbiIsCiAgICAgICAgICAgICAgICAgICJ3Yi5yYXRpbyIsImR1bm4yIiwiYXZnLnNpbHdpZHRoIikKY2x1c3Quc2l6ZSA8LSBjKCJjbHVzdGVyLnNpemUiKQpzdGF0cy5uYW1lcyA8LSBjKCkKcm93LmNsdXN0IDwtIGMoKQpvdXRwdXQuc3RhdHMgPC0gbWF0cml4KG5jb2wgPSBrLCBucm93ID0gbGVuZ3RoKGNsdXN0LmFzc2VzcykpCmNsdXN0ZXIuc2l6ZXMgPC0gbWF0cml4KG5jb2wgPSBrLCBucm93ID0gaykKZm9yKGkgaW4gYygxOmspKXsKICByb3cuY2x1c3RbaV0gPC0gcGFzdGUoIkNsdXN0ZXItIiwgaSwgIiBzaXplIikKfQpmb3IoaSBpbiBjKDI6aykpewogIHN0YXRzLm5hbWVzW2ldIDwtIHBhc3RlKCJUZXN0IiwgaS0xKQogIAogIGZvcihqIGluIHNlcV9hbG9uZyhjbHVzdC5hc3Nlc3MpKXsKICAgIG91dHB1dC5zdGF0c1tqLCBpXSA8LSB1bmxpc3QoY2x1c3Rlci5zdGF0cyhkID0gZGlzdCwgY2x1c3RlcmluZyA9IGN1dHJlZSh0cmVlLCBrID0gaSkpW2NsdXN0LmFzc2Vzc10pW2pdCiAgICAKICB9CiAgCiAgZm9yKGQgaW4gMTprKSB7CiAgICBjbHVzdGVyLnNpemVzW2QsIGldIDwtIHVubGlzdChjbHVzdGVyLnN0YXRzKGQgPSBkaXN0LCBjbHVzdGVyaW5nID0gY3V0cmVlKHRyZWUsIGsgPSBpKSlbY2x1c3Quc2l6ZV0pW2RdCiAgICBkaW0oY2x1c3Rlci5zaXplc1tkLCBpXSkgPC0gYyhsZW5ndGgoY2x1c3Rlci5zaXplc1tpXSksIDEpCiAgICBjbHVzdGVyLnNpemVzW2QsIGldCiAgICAKICB9Cn0Kb3V0cHV0LnN0YXRzLmRmIDwtIGRhdGEuZnJhbWUob3V0cHV0LnN0YXRzKQpjbHVzdGVyLnNpemVzIDwtIGRhdGEuZnJhbWUoY2x1c3Rlci5zaXplcykKY2x1c3Rlci5zaXplc1tpcy5uYShjbHVzdGVyLnNpemVzKV0gPC0gMApyb3dzLmFsbCA8LSBjKGNsdXN0LmFzc2Vzcywgcm93LmNsdXN0KQojIHJvd25hbWVzKG91dHB1dC5zdGF0cy5kZikgPC0gY2x1c3QuYXNzZXNzCm91dHB1dCA8LSByYmluZChvdXRwdXQuc3RhdHMuZGYsIGNsdXN0ZXIuc2l6ZXMpWyAsLTFdCmNvbG5hbWVzKG91dHB1dCkgPC0gc3RhdHMubmFtZXNbMjprXQpyb3duYW1lcyhvdXRwdXQpIDwtIHJvd3MuYWxsCmlzLm51bSA8LSBzYXBwbHkob3V0cHV0LCBpcy5udW1lcmljKQpvdXRwdXRbaXMubnVtXSA8LSBsYXBwbHkob3V0cHV0W2lzLm51bV0sIHJvdW5kLCAyKQpvdXRwdXQKfQojIEkgYW0gY2FwcGluZyB0aGUgbWF4aW11bSBhbW91dCBvZiBjbHVzdGVycyBieSA3CiMgSSB3YW50IHRvIGNob29zZSBhIHJlYXNvbmFibGUgbnVtYmVyLCBiYXNlZCBvbiB3aGljaCBJIHdpbGwgYmUgYWJsZSB0byBzZWUgYmFzaWMgZGlmZmVyZW5jZXMgYmV0d2VlbiBjdXN0b21lciBncm91cHMgYXMgYSByZXN1bHQKc3RhdHMuZGYuZGl2aXNpdmUgPC0gY3N0YXRzLnRhYmxlKGRpc3RhbmNlLCBkaXYsIDcpCnN0YXRzLmRmLmRpdmlzaXZlCgpzdGF0cy5kZi5hZ2dsIDwtY3N0YXRzLnRhYmxlKGRpc3RhbmNlLCBhZ2csIDcpICNjb21wbGV0ZSBsaW5rYWdlcyBsb29rcyBsaWtlIHRoZSBtb3N0IGJhbGFuY2VkIGFwcHJvYWNoCnN0YXRzLmRmLmFnZ2wKCiNjb25mdXNpb25NYXRyaXgodHJhaW5fc21hbGwsICkKYGBgCgpgYGB7cn0KbGlicmFyeSgiZ2dwbG90MiIpCmxpYnJhcnkoInJlc2hhcGUyIikKbGlicmFyeSgicHVycnIiKQpsaWJyYXJ5KCJkcGx5ciIpCiMgbGV0J3Mgc3RhcnQgd2l0aCBhIGRlbmRyb2dyYW0KbGlicmFyeSgiZGVuZGV4dGVuZCIpCmRlbmRybyA8LSBhcy5kZW5kcm9ncmFtKGFnZykKZGVuZHJvLmNvbCA8LSBkZW5kcm8gJT4lCiAgc2V0KCJicmFuY2hlc19rX2NvbG9yIiwgayA9IDgsIHZhbHVlID0gICBjKCJkYXJrc2xhdGVncmF5IiwgImRhcmtzbGF0ZWdyYXk0IiwgImRhcmtzbGF0ZWdyYXkzIiwgImdvbGQzIiwgImRhcmtjeWFuIiwgImN5YW4zIiwgImdvbGQzIikpICU+JQogIHNldCgiYnJhbmNoZXNfbHdkIiwgMC42KSAlPiUKICBzZXQoImxhYmVsc19jb2xvcnMiLCAKICAgICAgdmFsdWUgPSBjKCJkYXJrc2xhdGVncmF5IikpICU+JSAKICBzZXQoImxhYmVsc19jZXgiLCAwLjUpCmdnZDEgPC0gYXMuZ2dkZW5kKGRlbmRyby5jb2wpCmdncGxvdChnZ2QxLCB0aGVtZSA9IHRoZW1lX21pbmltYWwoKSkgKwogIGxhYnMoeCA9ICJOdW0uIG9ic2VydmF0aW9ucyIsIHkgPSAiSGVpZ2h0IiwgdGl0bGUgPSAiRGVuZHJvZ3JhbSwgayA9IDgiKQoKCgpgYGAKIyMgQXJib2xlcyBkZSBEZWNpc2lvbgpgYGB7cn0KIyMgYzUwCgpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KE1BU1MpICAgICAgICAjIGZvciBvYnRhaW5pbmcgZGF0YQpsaWJyYXJ5KHRpZHl2ZXJzZSkgICMgZm9yIGRhdGEgcHJvY2Vzc2luZwpsaWJyYXJ5KHJwYXJ0KSAgICAgICMgZm9yIENBUlQgZGVjaXNpb24gdHJlZQpsaWJyYXJ5KHJwYXJ0LnBsb3QpICMgZm9yIHBsb3R0aW5nIENBUlQKbGlicmFyeShjYXJldCkgICAgICAjIGZvciBjb25mdXNpb24gbWF0cml4IGFuZCBtb3JlCmxpYnJhcnkocnNhbXBsZSkgICAgIyBmb3IgZGF0YSBzcGxpdHRpbmcKbGlicmFyeShkYXRhLnRhYmxlKQpsaWJyYXJ5KEM1MCkKCgojbGV2ZWxzKGNoaWNhZ29fY3JpbWUkbG9jYXRpb25fZGVzY3JpcHRpb24pWzFdID0gIk5vbmUiCiMjIENyZWF0aW5nIGEgdHJhaW5pbmcgYW5kIHRlc3QgZGF0YXNldHMKc2V0LnNlZWQoMTIzNCkKCmNoaWNhZ29fY3JpbWVfdHJlZXMgPC0gc3Vic2V0KGNoaWNhZ29fY3JpbWVfc3Vic2V0LCBzZWxlY3Q9LWMobG9jYXRpb25fZGVzY3JpcHRpb24sY2FzZV9udW1iZXIsYmxvY2ssd2FyZCxkZXNjcmlwdGlvbixkYXksbW9udGgsbGF0aXR1ZGUsbG9uZ2l0dWRlKSkKY2hpY2Fnb19jcmltZV90cmVlc190ciA8LSBzdWJzZXQoY2hpY2Fnb19jcmltZV9zdWJzZXRfdHIsIHNlbGVjdD0tYyhsb2NhdGlvbl9kZXNjcmlwdGlvbixjYXNlX251bWJlcixibG9jayx3YXJkLGRlc2NyaXB0aW9uLGRheSxtb250aCxsYXRpdHVkZSxsb25naXR1ZGUpKQoKbGlicmFyeShkcGx5cikKY2hpY2Fnb19jcmltZV90cmVlcyAlPiUgbXV0YXRlX2lmKGlzLmZhY3RvciwgYXMuY2hhcmFjdGVyKSAtPiBjaGljYWdvX2NyaW1lX3RyZWVzCmNoaWNhZ29fY3JpbWVfdHJlZXNfdHIgJT4lIG11dGF0ZV9pZihpcy5mYWN0b3IsIGFzLmNoYXJhY3RlcikgLT4gY2hpY2Fnb19jcmltZV90cmVlc190cgoKY2hpY2Fnb19jcmltZV90cmVlcyRwcmltYXJ5X3R5cGVbY2hpY2Fnb19jcmltZV90cmVlcyRwcmltYXJ5X3R5cGUgPT0gIlJPQkJFUlkiXSA8LSAiUk9CIgpjaGljYWdvX2NyaW1lX3RyZWVzJHByaW1hcnlfdHlwZVtjaGljYWdvX2NyaW1lX3RyZWVzJHByaW1hcnlfdHlwZSA9PSAiTkFSQ09USUNTIl0gPC0gIk5BUiIKY2hpY2Fnb19jcmltZV90cmVlcyRwcmltYXJ5X3R5cGVbY2hpY2Fnb19jcmltZV90cmVlcyRwcmltYXJ5X3R5cGUgPT0gIkFTU0FVTFQiXSA8LSAiQVNTIgpjaGljYWdvX2NyaW1lX3RyZWVzJHByaW1hcnlfdHlwZVtjaGljYWdvX2NyaW1lX3RyZWVzJHByaW1hcnlfdHlwZSA9PSAiV0VBUE9OUyBWSU9MQVRJT04iXSA8LSAiV1YiCmNoaWNhZ29fY3JpbWVfdHJlZXMkcHJpbWFyeV90eXBlW2NoaWNhZ29fY3JpbWVfdHJlZXMkcHJpbWFyeV90eXBlID09ICJDUklNSU5BTCBEQU1BR0UiXSA8LSAiQ0QiCmNoaWNhZ29fY3JpbWVfdHJlZXMkcHJpbWFyeV90eXBlW2NoaWNhZ29fY3JpbWVfdHJlZXMkcHJpbWFyeV90eXBlID09ICJWSU9MRU5UIENSSU1FIl0gPC0gIlZDIgpjaGljYWdvX2NyaW1lX3RyZWVzJHByaW1hcnlfdHlwZVtjaGljYWdvX2NyaW1lX3RyZWVzJHByaW1hcnlfdHlwZSA9PSAiREVDRVBUSVZFIFBSQUNUSUNFIl0gPC0gIkRQIgpjaGljYWdvX2NyaW1lX3RyZWVzJHByaW1hcnlfdHlwZVtjaGljYWdvX2NyaW1lX3RyZWVzJHByaW1hcnlfdHlwZSA9PSAiVEhFRlQiXSA8LSAiVEgiCgpjaGljYWdvX2NyaW1lX3RyZWVzX3RyJHByaW1hcnlfdHlwZVtjaGljYWdvX2NyaW1lX3RyZWVzX3RyJHByaW1hcnlfdHlwZSA9PSAiUk9CQkVSWSJdIDwtICJST0IiCmNoaWNhZ29fY3JpbWVfdHJlZXNfdHIkcHJpbWFyeV90eXBlW2NoaWNhZ29fY3JpbWVfdHJlZXNfdHIkcHJpbWFyeV90eXBlID09ICJOQVJDT1RJQ1MiXSA8LSAiTkFSIgpjaGljYWdvX2NyaW1lX3RyZWVzX3RyJHByaW1hcnlfdHlwZVtjaGljYWdvX2NyaW1lX3RyZWVzX3RyJHByaW1hcnlfdHlwZSA9PSAiQVNTQVVMVCJdIDwtICJBU1MiCmNoaWNhZ29fY3JpbWVfdHJlZXNfdHIkcHJpbWFyeV90eXBlW2NoaWNhZ29fY3JpbWVfdHJlZXNfdHIkcHJpbWFyeV90eXBlID09ICJXRUFQT05TIFZJT0xBVElPTiJdIDwtICJXViIKY2hpY2Fnb19jcmltZV90cmVlc190ciRwcmltYXJ5X3R5cGVbY2hpY2Fnb19jcmltZV90cmVlc190ciRwcmltYXJ5X3R5cGUgPT0gIkNSSU1JTkFMIERBTUFHRSJdIDwtICJDRCIKY2hpY2Fnb19jcmltZV90cmVlc190ciRwcmltYXJ5X3R5cGVbY2hpY2Fnb19jcmltZV90cmVlc190ciRwcmltYXJ5X3R5cGUgPT0gIlZJT0xFTlQgQ1JJTUUiXSA8LSAiVkMiCmNoaWNhZ29fY3JpbWVfdHJlZXNfdHIkcHJpbWFyeV90eXBlW2NoaWNhZ29fY3JpbWVfdHJlZXNfdHIkcHJpbWFyeV90eXBlID09ICJERUNFUFRJVkUgUFJBQ1RJQ0UiXSA8LSAiRFAiCmNoaWNhZ29fY3JpbWVfdHJlZXNfdHIkcHJpbWFyeV90eXBlW2NoaWNhZ29fY3JpbWVfdHJlZXNfdHIkcHJpbWFyeV90eXBlID09ICJUSEVGVCJdIDwtICJUSCIKCiN0cmFpbl9jNTA8LSBjaGljYWdvX2NyaW1lX3RyZWVzX3RyCiN0ZXN0X2M1MDwtIGNoaWNhZ29fY3JpbWVfdHJlZXMKCmNyaW1lX3NwbGl0X2M1MDwtIGluaXRpYWxfc3BsaXQoc3Vic2V0KGNoaWNhZ29fY3JpbWVfc3Vic2V0X3RyLCBzZWxlY3Q9LWMobG9jYXRpb25fZGVzY3JpcHRpb24sY2FzZV9udW1iZXIsYmxvY2ssd2FyZCxkZXNjcmlwdGlvbixkYXksbW9udGgsbGF0aXR1ZGUsbG9uZ2l0dWRlKSksIHByb3A9MC44KQp0cmFpbl9jNTA8LSB0cmFpbmluZyhjcmltZV9zcGxpdF9jNTApCnRlc3RfYzUwPC0gdGVzdGluZyhjcmltZV9zcGxpdF9jNTApCgojdHJhaW5fYzUwJGxvY2F0aW9uX2Rlc2NyaXB0aW9uIDwtIGFzLmZhY3Rvcih0cmFpbl9jNTAkbG9jYXRpb25fZGVzY3JpcHRpb24pCiN0ZXN0X2M1MCRsb2NhdGlvbl9kZXNjcmlwdGlvbiA8LSBhcy5mYWN0b3IodGVzdF9jNTAkbG9jYXRpb25fZGVzY3JpcHRpb24pCiN0cmFpbl9jNTAkYXJyZXN0IDwtIGFzLm51bWVyaWModHJhaW5fYzUwJGFycmVzdCwgdW5pcXVlKHRyYWluX2M1MCRhcnJlc3QpKQojdGVzdF9jNTAkYXJyZXN0IDwtIGFzLm51bWVyaWModGVzdF9jNTAkYXJyZXN0LCB1bmlxdWUodGVzdF9jNTAkYXJyZXN0KSkKI3RyYWluX2M1MCRwcmltYXJ5X3R5cGUgPC0gYXMubnVtZXJpYyh0cmFpbl9jNTAkcHJpbWFyeV90eXBlLCB1bmlxdWUodHJhaW5fYzUwJHByaW1hcnlfdHlwZSkpCiN0ZXN0X2M1MCRwcmltYXJ5X3R5cGUgPC0gYXMubnVtZXJpYyh0ZXN0X2M1MCRwcmltYXJ5X3R5cGUsIHVuaXF1ZSh0ZXN0X2M1MCRwcmltYXJ5X3R5cGUpKQojdHJhaW5fYzUwJGxvY2F0aW9uX2Rlc2NyaXB0aW9uIDwtIGFzLm51bWVyaWModHJhaW5fYzUwJGxvY2F0aW9uX2Rlc2NyaXB0aW9uLCB1bmlxdWUodHJhaW5fYzUwJGxvY2F0aW9uX2Rlc2NyaXB0aW9uKSkKI3Rlc3RfYzUwJGxvY2F0aW9uX2Rlc2NyaXB0aW9uIDwtIGFzLm51bWVyaWModGVzdF9jNTAkbG9jYXRpb25fZGVzY3JpcHRpb24sIHVuaXF1ZSh0ZXN0X2M1MCRsb2NhdGlvbl9kZXNjcmlwdGlvbikpCiN0cmFpbl9jNTAkZGlzdHJpY3QgPC0gYXMubnVtZXJpYyh0cmFpbl9jNTAkZGlzdHJpY3QsIHVuaXF1ZSh0cmFpbl9jNTAkZGlzdHJpY3QpKQojdGVzdF9jNTAkZGlzdHJpY3QgPC0gYXMubnVtZXJpYyh0ZXN0X2M1MCRkaXN0cmljdCwgdW5pcXVlKHRlc3RfYzUwJGRpc3RyaWN0KSkKdHJhaW5fYzUwJGFycmVzdCA8LSBhcy5mYWN0b3IodHJhaW5fYzUwJGFycmVzdCkKdGVzdF9jNTAkYXJyZXN0IDwtIGFzLmZhY3Rvcih0ZXN0X2M1MCRhcnJlc3QpCnRyYWluX2M1MCRkaXN0cmljdCA8LSBhcy5mYWN0b3IodHJhaW5fYzUwJGRpc3RyaWN0KQp0ZXN0X2M1MCRkaXN0cmljdCA8LSBhcy5mYWN0b3IodGVzdF9jNTAkZGlzdHJpY3QpCnRyYWluX2M1MCRwcmltYXJ5X3R5cGUgPC0gYXMuZmFjdG9yKHRyYWluX2M1MCRwcmltYXJ5X3R5cGUpCnRlc3RfYzUwJHByaW1hcnlfdHlwZSA8LSBhcy5mYWN0b3IodGVzdF9jNTAkcHJpbWFyeV90eXBlKQoKCiNDcmVhdGluZyB0aGUgZGVjaXNpb24gdHJlZSBhbGdvcml0aG0gQzQuNSAKdHJlZV9yZXN1bHQgPC0gQzUuMChwcmltYXJ5X3R5cGUgIH4gLiwgZGF0YT10cmFpbl9jNTAsIGNvbnRyb2wgPSBDNS4wQ29udHJvbChub0dsb2JhbFBydW5pbmcgPSBGQUxTRSwgQ0Y9IDAuMikpICAjSGlnaGVyIENGIGxlc3MgcHJ1bm5pbmcKc3VtbWFyeSh0cmVlX3Jlc3VsdCkKI1Bsb3R0aW5nIHRoZSB0cmVlCnBsb3QodHJlZV9yZXN1bHQsc3VidHJlZT1OVUxMKQoKIyMgUFJFRElDVElPTgojUHJlZGljdGlvbiBvZiBuZXcgY2FzZXMgZnJvbSB0aGUgdGVzdCBkYXRhc2V0CnByZWRpY3Rpb25zIDwtIHByZWRpY3QodHJlZV9yZXN1bHQsIG5ld2RhdGEgPSB0ZXN0X2M1MCwgdHlwZSA9ImNsYXNzIikKCiN0YWJsZShwcmVkaWN0aW9uPXByZWRpY3Rpb25zLCByZWFsPSBjcmltZV90ZXN0X2M1MCRwcmltYXJ5X3R5cGUpCiNjcmltZV90ZXN0X2M1MCRwcmltYXJ5X3R5cGUgPC0gZmFjdG9yKGNyaW1lX3Rlc3RfYzUwJHByaW1hcnlfdHlwZSkKZXJyb3JfY2xhc3NpZmljYXRpb24gPC0gbWVhbihwcmVkaWN0aW9ucyAhPSB0ZXN0X2M1MCRwcmltYXJ5X3R5cGUpCgpwYXN0ZSgiVGhlIGNsYXNzaWZpY2F0aW9uIGVycm9yIGluIHRlc3Qgc2V0IGlzOiIsIDEwMCplcnJvcl9jbGFzc2lmaWNhdGlvbiwgIiUiLAogICAgICBzdW0ocHJlZGljdGlvbnM9PXRlc3RfYzUwJHByaW1hcnlfdHlwZSksCiAgICAgICJjb3JyZWN0IGNsYXNzaWZpZWQgY2FzZXMgZnJvbSIsIGxlbmd0aChwcmVkaWN0aW9ucykpCgpwcmVkX3RyYWluIDwtIHByZWRpY3QodHJlZV9yZXN1bHQsIG5ld2RhdGEgPSB0cmFpbl9jNTApCiNjb25mdXNpb25NYXRyaXgocHJlZF90cmFpbiwgY3JpbWVfdHJhaW4kZGlzdHJpY3QpCiNwcmVkX3RyYWluPC1yb3VuZChwcmVkX3RyYWluKQojdGFibGUocHJlZGljdGlvbj1wcmVkX3RyYWluLCByZWFsPSBjcmltZV90cmFpbl9jNTAkYXJyZXN0KQoKZXJyb3JfY2xhc3NpZmljYXRpb24gPC0gbWVhbihwcmVkX3RyYWluICE9IHRyYWluX2M1MCRwcmltYXJ5X3R5cGUpCgpwYXN0ZSgiVGhlIGNsYXNzaWZpY2F0aW9uIGVycm9yIGluIHRyYWluIHNldCBpczoiLCAxMDAqZXJyb3JfY2xhc3NpZmljYXRpb24sICIlIiwKICAgICAgc3VtKHByZWRfdHJhaW49PXRyYWluX2M1MCRwcmltYXJ5X3R5cGUpLAogICAgICAiY29ycmVjdCBjbGFzc2lmaWVkIGNhc2VzIGZyb20iLCBsZW5ndGgocHJlZF90cmFpbikpCgoKYGBgCmBgYHtyfQojQ3JlYXRpbmcgdGhlIGRlY2lzaW9uIHRyZWUgYWxnb3JpdGhtIEM0LjUgCnRyZWVfcmVzdWx0IDwtIEM1LjAoZGlzdHJpY3QgIH4gLiwgZGF0YT10cmFpbl9jNTAsIGNvbnRyb2wgPSBDNS4wQ29udHJvbChub0dsb2JhbFBydW5pbmcgPSBGQUxTRSwgQ0Y9IDAuMSkpICAjSGlnaGVyIENGIGxlc3MgcHJ1bm5pbmcKc3VtbWFyeSh0cmVlX3Jlc3VsdCkKI1Bsb3R0aW5nIHRoZSB0cmVlCnBsb3QodHJlZV9yZXN1bHQsZmFjbGVuPTEwLCBjbGlwLmZhY3M9VFJVRSxzdWJ0cmVlPU5VTEwsIHR3ZWFrPTEsIGRpZ2l0cz0yKQoKIyMgUFJFRElDVElPTgojUHJlZGljdGlvbiBvZiBuZXcgY2FzZXMgZnJvbSB0aGUgdGVzdCBkYXRhc2V0CnByZWRpY3Rpb25zIDwtIHByZWRpY3QodHJlZV9yZXN1bHQsIG5ld2RhdGEgPSB0ZXN0X2M1MCwgdHlwZSA9ImNsYXNzIikKCiN0YWJsZShwcmVkaWN0aW9uPXByZWRpY3Rpb25zLCByZWFsPSBjcmltZV90ZXN0X2M1MCRwcmltYXJ5X3R5cGUpCiNjcmltZV90ZXN0X2M1MCRwcmltYXJ5X3R5cGUgPC0gZmFjdG9yKGNyaW1lX3Rlc3RfYzUwJHByaW1hcnlfdHlwZSkKZXJyb3JfY2xhc3NpZmljYXRpb24gPC0gbWVhbihwcmVkaWN0aW9ucyAhPSB0ZXN0X2M1MCRkaXN0cmljdCkKCnBhc3RlKCJUaGUgY2xhc3NpZmljYXRpb24gZXJyb3IgaW4gdGVzdCBzZXQgaXM6IiwgMTAwKmVycm9yX2NsYXNzaWZpY2F0aW9uLCAiJSIsCiAgICAgIHN1bShwcmVkaWN0aW9ucz09dGVzdF9jNTAkZGlzdHJpY3QpLAogICAgICAiY29ycmVjdCBjbGFzc2lmaWVkIGNhc2VzIGZyb20iLCBsZW5ndGgocHJlZGljdGlvbnMpKQoKcHJlZF90cmFpbiA8LSBwcmVkaWN0KHRyZWVfcmVzdWx0LCBuZXdkYXRhID0gdHJhaW5fYzUwKQojY29uZnVzaW9uTWF0cml4KHByZWRfdHJhaW4sIGNyaW1lX3RyYWluJGRpc3RyaWN0KQojcHJlZF90cmFpbjwtcm91bmQocHJlZF90cmFpbikKI3RhYmxlKHByZWRpY3Rpb249cHJlZF90cmFpbiwgcmVhbD0gY3JpbWVfdHJhaW5fYzUwJGFycmVzdCkKCmVycm9yX2NsYXNzaWZpY2F0aW9uIDwtIG1lYW4ocHJlZF90cmFpbiAhPSB0cmFpbl9jNTAkZGlzdHJpY3QpCgpwYXN0ZSgiVGhlIGNsYXNzaWZpY2F0aW9uIGVycm9yIGluIHRyYWluIHNldCBpczoiLCAxMDAqZXJyb3JfY2xhc3NpZmljYXRpb24sICIlIiwKICAgICAgc3VtKHByZWRfdHJhaW49PXRyYWluX2M1MCRkaXN0cmljdCksCiAgICAgICJjb3JyZWN0IGNsYXNzaWZpZWQgY2FzZXMgZnJvbSIsIGxlbmd0aChwcmVkX3RyYWluKSkKYGBgCmBgYHtyfQojQ3JlYXRpbmcgdGhlIGRlY2lzaW9uIHRyZWUgYWxnb3JpdGhtIEM0LjUgCnRyZWVfcmVzdWx0IDwtIEM1LjAoYXJyZXN0ICB+IC4sIGRhdGE9dHJhaW5fYzUwLCBjb250cm9sID0gQzUuMENvbnRyb2wobm9HbG9iYWxQcnVuaW5nID0gRkFMU0UsIENGPSAwLjkpKSAgI0hpZ2hlciBDRiBsZXNzIHBydW5uaW5nCnN1bW1hcnkodHJlZV9yZXN1bHQpCiNQbG90dGluZyB0aGUgdHJlZQpwbG90KHRyZWVfcmVzdWx0LGZhY2xlbj0xMCwgY2xpcC5mYWNzPVRSVUUsc3VidHJlZT1OVUxMLCB0d2Vhaz0xLCBkaWdpdHM9MikKCiMjIFBSRURJQ1RJT04KI1ByZWRpY3Rpb24gb2YgbmV3IGNhc2VzIGZyb20gdGhlIHRlc3QgZGF0YXNldApwcmVkaWN0aW9ucyA8LSBwcmVkaWN0KHRyZWVfcmVzdWx0LCBuZXdkYXRhID0gdGVzdF9jNTAsIHR5cGUgPSJjbGFzcyIpCgojdGFibGUocHJlZGljdGlvbj1wcmVkaWN0aW9ucywgcmVhbD0gY3JpbWVfdGVzdF9jNTAkcHJpbWFyeV90eXBlKQojY3JpbWVfdGVzdF9jNTAkcHJpbWFyeV90eXBlIDwtIGZhY3RvcihjcmltZV90ZXN0X2M1MCRwcmltYXJ5X3R5cGUpCmVycm9yX2NsYXNzaWZpY2F0aW9uIDwtIG1lYW4ocHJlZGljdGlvbnMgIT0gdGVzdF9jNTAkYXJyZXN0KQoKcGFzdGUoIlRoZSBjbGFzc2lmaWNhdGlvbiBlcnJvciBpbiB0ZXN0IHNldCBpczoiLCAxMDAqZXJyb3JfY2xhc3NpZmljYXRpb24sICIlIiwKICAgICAgc3VtKHByZWRpY3Rpb25zPT10ZXN0X2M1MCRhcnJlc3QpLAogICAgICAiY29ycmVjdCBjbGFzc2lmaWVkIGNhc2VzIGZyb20iLCBsZW5ndGgocHJlZGljdGlvbnMpKQoKcHJlZF90cmFpbiA8LSBwcmVkaWN0KHRyZWVfcmVzdWx0LCBuZXdkYXRhID0gdHJhaW5fYzUwKQojY29uZnVzaW9uTWF0cml4KHByZWRfdHJhaW4sIGNyaW1lX3RyYWluJGRpc3RyaWN0KQojcHJlZF90cmFpbjwtcm91bmQocHJlZF90cmFpbikKI3RhYmxlKHByZWRpY3Rpb249cHJlZF90cmFpbiwgcmVhbD0gY3JpbWVfdHJhaW5fYzUwJGFycmVzdCkKCmVycm9yX2NsYXNzaWZpY2F0aW9uIDwtIG1lYW4ocHJlZF90cmFpbiAhPSB0cmFpbl9jNTAkYXJyZXN0KQoKcGFzdGUoIlRoZSBjbGFzc2lmaWNhdGlvbiBlcnJvciBpbiB0cmFpbiBzZXQgaXM6IiwgMTAwKmVycm9yX2NsYXNzaWZpY2F0aW9uLCAiJSIsCiAgICAgIHN1bShwcmVkX3RyYWluPT10cmFpbl9jNTAkYXJyZXN0KSwKICAgICAgImNvcnJlY3QgY2xhc3NpZmllZCBjYXNlcyBmcm9tIiwgbGVuZ3RoKHByZWRfdHJhaW4pKQpgYGAKCgpgYGB7cn0KI2xldmVscyhjaGljYWdvX2NyaW1lJGxvY2F0aW9uX2Rlc2NyaXB0aW9uKVsxXSA9ICJOb25lIgojIyBDcmVhdGluZyBhIHRyYWluaW5nIGFuZCB0ZXN0IGRhdGFzZXRzCnNldC5zZWVkKDEyMzQpCiNhc3NhdWx0IDwtIHN1YnNldChhc3NhdWx0LCBzZWxlY3Q9LWMobG9jYXRpb25fZGVzY3JpcHRpb24pKQojYXNzYXVsdF90ciA8LSBzdWJzZXQoYXNzYXVsdF90ciwgc2VsZWN0PS1jKGxvY2F0aW9uX2Rlc2NyaXB0aW9uKSkKCmFzc2F1bHRfdHIgPC0gc3Vic2V0KGFzc2F1bHRfdHIsIGRpc3RyaWN0PT0iMyIgfCBkaXN0cmljdCA9PSAiNCIgfCBkaXN0cmljdCA9PSAiNSIgfCBkaXN0cmljdD09IjYiIHwgZGlzdHJpY3QgPT0gIjciIHwgZGlzdHJpY3Q9PSI4IiB8IGRpc3RyaWN0ID09ICIxIiB8IGRpc3RyaWN0ID09ICIxOCIgfCBkaXN0cmljdCA9PSAiOSIgfCBkaXN0cmljdD09IjEwIiB8IGRpc3RyaWN0ID09ICIyMiIgfCBkaXN0cmljdCA9PSAiMTUiICkKYXNzYXVsdCA8LSBzdWJzZXQoYXNzYXVsdCwgZGlzdHJpY3Q9PSIzIiB8IGRpc3RyaWN0ID09ICI0IiB8IGRpc3RyaWN0ID09ICI1IiB8IGRpc3RyaWN0PT0iNiIgfCBkaXN0cmljdCA9PSAiNyIgfCBkaXN0cmljdD09IjgiIHwgZGlzdHJpY3QgPT0gIjEiIHwgZGlzdHJpY3QgPT0gIjE4IiB8IGRpc3RyaWN0ID09ICI5IiB8IGRpc3RyaWN0PT0iMTAiIHwgZGlzdHJpY3QgPT0gIjIyIiB8IGRpc3RyaWN0ID09ICIxNSIgKQoKI3RyYWluX2M1MDwtIHN1YnNldChhc3NhdWx0X3RyLCBzZWxlY3Q9LWMoY2FzZV9udW1iZXIsYmxvY2ssd2FyZCxkZXNjcmlwdGlvbixkYXksbW9udGgsbGF0aXR1ZGUsbG9uZ2l0dWRlKSkKI3Rlc3RfYzUwPC0gc3Vic2V0KGFzc2F1bHQsIHNlbGVjdD0tYyhjYXNlX251bWJlcixibG9jayx3YXJkLGRlc2NyaXB0aW9uLGRheSxtb250aCxsYXRpdHVkZSxsb25naXR1ZGUpKQoKY3JpbWVfc3BsaXRfYzUwPC0gaW5pdGlhbF9zcGxpdChzdWJzZXQoYXNzYXVsdF90ciwgc2VsZWN0PS1jKGNhc2VfbnVtYmVyLGJsb2NrLHdhcmQsZGVzY3JpcHRpb24sZGF5LG1vbnRoLGxhdGl0dWRlLGxvbmdpdHVkZSkpLCBwcm9wPTAuOCkKdHJhaW5fYzUwPC0gdHJhaW5pbmcoY3JpbWVfc3BsaXRfYzUwKQp0ZXN0X2M1MDwtIHRlc3RpbmcoY3JpbWVfc3BsaXRfYzUwKQoKdHJhaW5fYzUwJGxvY2F0aW9uX2Rlc2NyaXB0aW9uIDwtIGFzLmZhY3Rvcih0cmFpbl9jNTAkbG9jYXRpb25fZGVzY3JpcHRpb24pCnRlc3RfYzUwJGxvY2F0aW9uX2Rlc2NyaXB0aW9uIDwtIGFzLmZhY3Rvcih0ZXN0X2M1MCRsb2NhdGlvbl9kZXNjcmlwdGlvbikKI3RyYWluX2M1MCRhcnJlc3QgPC0gYXMubnVtZXJpYyh0cmFpbl9jNTAkYXJyZXN0LCB1bmlxdWUodHJhaW5fYzUwJGFycmVzdCkpCiN0ZXN0X2M1MCRhcnJlc3QgPC0gYXMubnVtZXJpYyh0ZXN0X2M1MCRhcnJlc3QsIHVuaXF1ZSh0ZXN0X2M1MCRhcnJlc3QpKQojdHJhaW5fYzUwJHByaW1hcnlfdHlwZSA8LSBhcy5udW1lcmljKHRyYWluX2M1MCRwcmltYXJ5X3R5cGUsIHVuaXF1ZSh0cmFpbl9jNTAkcHJpbWFyeV90eXBlKSkKI3Rlc3RfYzUwJHByaW1hcnlfdHlwZSA8LSBhcy5udW1lcmljKHRlc3RfYzUwJHByaW1hcnlfdHlwZSwgdW5pcXVlKHRlc3RfYzUwJHByaW1hcnlfdHlwZSkpCnRyYWluX2M1MCRsb2NhdGlvbl9kZXNjcmlwdGlvbiA8LSBhcy5udW1lcmljKHRyYWluX2M1MCRsb2NhdGlvbl9kZXNjcmlwdGlvbiwgdW5pcXVlKHRyYWluX2M1MCRsb2NhdGlvbl9kZXNjcmlwdGlvbikpCnRlc3RfYzUwJGxvY2F0aW9uX2Rlc2NyaXB0aW9uIDwtIGFzLm51bWVyaWModGVzdF9jNTAkbG9jYXRpb25fZGVzY3JpcHRpb24sIHVuaXF1ZSh0ZXN0X2M1MCRsb2NhdGlvbl9kZXNjcmlwdGlvbikpCiN0cmFpbl9jNTAkZGlzdHJpY3QgPC0gYXMubnVtZXJpYyh0cmFpbl9jNTAkZGlzdHJpY3QsIHVuaXF1ZSh0cmFpbl9jNTAkZGlzdHJpY3QpKQojdGVzdF9jNTAkZGlzdHJpY3QgPC0gYXMubnVtZXJpYyh0ZXN0X2M1MCRkaXN0cmljdCwgdW5pcXVlKHRlc3RfYzUwJGRpc3RyaWN0KSkKdHJhaW5fYzUwJGFycmVzdCA8LSBhcy5mYWN0b3IodHJhaW5fYzUwJGFycmVzdCkKdGVzdF9jNTAkYXJyZXN0IDwtIGFzLmZhY3Rvcih0ZXN0X2M1MCRhcnJlc3QpCnRyYWluX2M1MCRkaXN0cmljdCA8LSBhcy5mYWN0b3IodHJhaW5fYzUwJGRpc3RyaWN0KQp0ZXN0X2M1MCRkaXN0cmljdCA8LSBhcy5mYWN0b3IodGVzdF9jNTAkZGlzdHJpY3QpCnRyYWluX2M1MCRkaXN0cmljdCA8LSBmYWN0b3IodHJhaW5fYzUwJGRpc3RyaWN0KQp0ZXN0X2M1MCRkaXN0cmljdCA8LSBmYWN0b3IodGVzdF9jNTAkZGlzdHJpY3QpCiN0cmFpbl9jNTAkcHJpbWFyeV90eXBlIDwtIGFzLmZhY3Rvcih0cmFpbl9jNTAkcHJpbWFyeV90eXBlKQojdGVzdF9jNTAkcHJpbWFyeV90eXBlIDwtIGFzLmZhY3Rvcih0ZXN0X2M1MCRwcmltYXJ5X3R5cGUpCgoKI0NyZWF0aW5nIHRoZSBkZWNpc2lvbiB0cmVlIGFsZ29yaXRobSBDNC41IAp0cmVlX3Jlc3VsdCA8LSBDNS4wKGRpc3RyaWN0ICB+IC4sIGRhdGE9dHJhaW5fYzUwLCBjb250cm9sID0gQzUuMENvbnRyb2wobm9HbG9iYWxQcnVuaW5nID0gRkFMU0UsIENGPSAwLjAwMDEpKSAgI0hpZ2hlciBDRiBsZXNzIHBydW5uaW5nCnN1bW1hcnkodHJlZV9yZXN1bHQpCiNQbG90dGluZyB0aGUgdHJlZQpwbG90KHRyZWVfcmVzdWx0LHN1YnRyZWU9TlVMTCkKCiMjIFBSRURJQ1RJT04KI1ByZWRpY3Rpb24gb2YgbmV3IGNhc2VzIGZyb20gdGhlIHRlc3QgZGF0YXNldApwcmVkaWN0aW9ucyA8LSBwcmVkaWN0KHRyZWVfcmVzdWx0LCBuZXdkYXRhID0gdGVzdF9jNTAsIHR5cGUgPSJjbGFzcyIpCgojdGFibGUocHJlZGljdGlvbj1wcmVkaWN0aW9ucywgcmVhbD0gY3JpbWVfdGVzdF9jNTAkcHJpbWFyeV90eXBlKQojY3JpbWVfdGVzdF9jNTAkcHJpbWFyeV90eXBlIDwtIGZhY3RvcihjcmltZV90ZXN0X2M1MCRwcmltYXJ5X3R5cGUpCmVycm9yX2NsYXNzaWZpY2F0aW9uIDwtIG1lYW4ocHJlZGljdGlvbnMgIT0gdGVzdF9jNTAkZGlzdHJpY3QpCgpwYXN0ZSgiVGhlIGNsYXNzaWZpY2F0aW9uIGVycm9yIGluIHRlc3Qgc2V0IGlzOiIsIDEwMCplcnJvcl9jbGFzc2lmaWNhdGlvbiwgIiUiLAogICAgICBzdW0ocHJlZGljdGlvbnM9PXRlc3RfYzUwJGRpc3RyaWN0KSwKICAgICAgImNvcnJlY3QgY2xhc3NpZmllZCBjYXNlcyBmcm9tIiwgbGVuZ3RoKHByZWRpY3Rpb25zKSkKCnByZWRfdHJhaW4gPC0gcHJlZGljdCh0cmVlX3Jlc3VsdCwgbmV3ZGF0YSA9IHRyYWluX2M1MCkKI2NvbmZ1c2lvbk1hdHJpeChwcmVkX3RyYWluLCBjcmltZV90cmFpbiRkaXN0cmljdCkKI3ByZWRfdHJhaW48LXJvdW5kKHByZWRfdHJhaW4pCiN0YWJsZShwcmVkaWN0aW9uPXByZWRfdHJhaW4sIHJlYWw9IGNyaW1lX3RyYWluX2M1MCRhcnJlc3QpCgplcnJvcl9jbGFzc2lmaWNhdGlvbiA8LSBtZWFuKHByZWRfdHJhaW4gIT0gdHJhaW5fYzUwJGRpc3RyaWN0KQoKcGFzdGUoIlRoZSBjbGFzc2lmaWNhdGlvbiBlcnJvciBpbiB0cmFpbiBzZXQgaXM6IiwgMTAwKmVycm9yX2NsYXNzaWZpY2F0aW9uLCAiJSIsCiAgICAgIHN1bShwcmVkX3RyYWluPT10cmFpbl9jNTAkZGlzdHJpY3QpLAogICAgICAiY29ycmVjdCBjbGFzc2lmaWVkIGNhc2VzIGZyb20iLCBsZW5ndGgocHJlZF90cmFpbikpCmBgYApgYGB7cn0KI2xldmVscyhjaGljYWdvX2NyaW1lJGxvY2F0aW9uX2Rlc2NyaXB0aW9uKVsxXSA9ICJOb25lIgojIyBDcmVhdGluZyBhIHRyYWluaW5nIGFuZCB0ZXN0IGRhdGFzZXRzCnNldC5zZWVkKDEyMzQpCiNjcmltaW5hbF9kYW1hZ2UgPC0gc3Vic2V0KGNyaW1pbmFsX2RhbWFnZSwgc2VsZWN0PS1jKGxvY2F0aW9uX2Rlc2NyaXB0aW9uKSkKI2NyaW1pbmFsX2RhbWFnZV90ciA8LSBzdWJzZXQoIGNyaW1pbmFsX2RhbWFnZV90ciwgc2VsZWN0PS1jKGxvY2F0aW9uX2Rlc2NyaXB0aW9uKSkKY3JpbWluYWxfZGFtYWdlX3RyIDwtIHN1YnNldChjcmltaW5hbF9kYW1hZ2VfdHIsIGRpc3RyaWN0PT0iMyIgfCBkaXN0cmljdCA9PSAiNCIgfCBkaXN0cmljdCA9PSAiNSIgfCBkaXN0cmljdD09IjYiIHwgZGlzdHJpY3QgPT0gIjciIHwgZGlzdHJpY3Q9PSI4IiB8IGRpc3RyaWN0ID09ICIxIiB8IGRpc3RyaWN0ID09ICIxOCIgIHwgZGlzdHJpY3QgPT0gIjkiIHwgZGlzdHJpY3Q9PSIyMCIgfCBkaXN0cmljdCA9PSAiMjUiIHwgZGlzdHJpY3QgPT0gIjExIikKY3JpbWluYWxfZGFtYWdlIDwtIHN1YnNldChjcmltaW5hbF9kYW1hZ2UsIGRpc3RyaWN0PT0iMyIgfCBkaXN0cmljdCA9PSAiNCIgfCBkaXN0cmljdCA9PSAiNSIgfCBkaXN0cmljdD09IjYiIHwgZGlzdHJpY3QgPT0gIjciIHwgZGlzdHJpY3Q9PSI4IiB8IGRpc3RyaWN0ID09ICIxIiB8IGRpc3RyaWN0ID09ICIxOCIgIHwgZGlzdHJpY3QgPT0gIjkiIHwgZGlzdHJpY3Q9PSIyMCIgfCBkaXN0cmljdCA9PSAiMjUiIHwgZGlzdHJpY3QgPT0gIjExIikKCnRyYWluX2M1MDwtIHN1YnNldChjcmltaW5hbF9kYW1hZ2VfdHIsIHNlbGVjdD0tYyhjYXNlX251bWJlcixibG9jayx3YXJkLGRlc2NyaXB0aW9uLGRheSxtb250aCxsYXRpdHVkZSxsb25naXR1ZGUpKQp0ZXN0X2M1MDwtIHN1YnNldChjcmltaW5hbF9kYW1hZ2UsIHNlbGVjdD0tYyhjYXNlX251bWJlcixibG9jayx3YXJkLGRlc2NyaXB0aW9uLGRheSxtb250aCxsYXRpdHVkZSxsb25naXR1ZGUpKQoKI2NyaW1lX3NwbGl0X2M1MDwtIGluaXRpYWxfc3BsaXQoc3Vic2V0KGNoaWNhZ29fY3JpbWVfc3Vic2V0X3RyLCBzZWxlY3Q9LWMoY2FzZV9udW1iZXIsYmxvY2ssd2FyZCxkZXNjcmlwdGlvbixkYXksbW9udGgsbGF0aXR1ZGUsbG9uZ2l0dWRlKSksIHByb3A9MC44KQojdHJhaW5fYzUwPC0gdHJhaW5pbmcoY3JpbWVfc3BsaXRfYzUwKQojdGVzdF9jNTA8LSB0ZXN0aW5nKGNyaW1lX3NwbGl0X2M1MCkKCnRyYWluX2M1MCRsb2NhdGlvbl9kZXNjcmlwdGlvbiA8LSBhcy5mYWN0b3IodHJhaW5fYzUwJGxvY2F0aW9uX2Rlc2NyaXB0aW9uKQp0ZXN0X2M1MCRsb2NhdGlvbl9kZXNjcmlwdGlvbiA8LSBhcy5mYWN0b3IodGVzdF9jNTAkbG9jYXRpb25fZGVzY3JpcHRpb24pCiN0cmFpbl9jNTAkYXJyZXN0IDwtIGFzLm51bWVyaWModHJhaW5fYzUwJGFycmVzdCwgdW5pcXVlKHRyYWluX2M1MCRhcnJlc3QpKQojdGVzdF9jNTAkYXJyZXN0IDwtIGFzLm51bWVyaWModGVzdF9jNTAkYXJyZXN0LCB1bmlxdWUodGVzdF9jNTAkYXJyZXN0KSkKI3RyYWluX2M1MCRwcmltYXJ5X3R5cGUgPC0gYXMubnVtZXJpYyh0cmFpbl9jNTAkcHJpbWFyeV90eXBlLCB1bmlxdWUodHJhaW5fYzUwJHByaW1hcnlfdHlwZSkpCiN0ZXN0X2M1MCRwcmltYXJ5X3R5cGUgPC0gYXMubnVtZXJpYyh0ZXN0X2M1MCRwcmltYXJ5X3R5cGUsIHVuaXF1ZSh0ZXN0X2M1MCRwcmltYXJ5X3R5cGUpKQojdHJhaW5fYzUwJGxvY2F0aW9uX2Rlc2NyaXB0aW9uIDwtIGFzLm51bWVyaWModHJhaW5fYzUwJGxvY2F0aW9uX2Rlc2NyaXB0aW9uLCB1bmlxdWUodHJhaW5fYzUwJGxvY2F0aW9uX2Rlc2NyaXB0aW9uKSkKI3Rlc3RfYzUwJGxvY2F0aW9uX2Rlc2NyaXB0aW9uIDwtIGFzLm51bWVyaWModGVzdF9jNTAkbG9jYXRpb25fZGVzY3JpcHRpb24sIHVuaXF1ZSh0ZXN0X2M1MCRsb2NhdGlvbl9kZXNjcmlwdGlvbikpCiN0cmFpbl9jNTAkZGlzdHJpY3QgPC0gYXMubnVtZXJpYyh0cmFpbl9jNTAkZGlzdHJpY3QsIHVuaXF1ZSh0cmFpbl9jNTAkZGlzdHJpY3QpKQojdGVzdF9jNTAkZGlzdHJpY3QgPC0gYXMubnVtZXJpYyh0ZXN0X2M1MCRkaXN0cmljdCwgdW5pcXVlKHRlc3RfYzUwJGRpc3RyaWN0KSkKdHJhaW5fYzUwJGFycmVzdCA8LSBhcy5mYWN0b3IodHJhaW5fYzUwJGFycmVzdCkKdGVzdF9jNTAkYXJyZXN0IDwtIGFzLmZhY3Rvcih0ZXN0X2M1MCRhcnJlc3QpCnRyYWluX2M1MCRkaXN0cmljdCA8LSBhcy5mYWN0b3IodHJhaW5fYzUwJGRpc3RyaWN0KQp0ZXN0X2M1MCRkaXN0cmljdCA8LSBhcy5mYWN0b3IodGVzdF9jNTAkZGlzdHJpY3QpCnRyYWluX2M1MCRkaXN0cmljdCA8LSBmYWN0b3IodHJhaW5fYzUwJGRpc3RyaWN0KQp0ZXN0X2M1MCRkaXN0cmljdCA8LSBmYWN0b3IodGVzdF9jNTAkZGlzdHJpY3QpCiN0cmFpbl9jNTAkcHJpbWFyeV90eXBlIDwtIGFzLmZhY3Rvcih0cmFpbl9jNTAkcHJpbWFyeV90eXBlKQojdGVzdF9jNTAkcHJpbWFyeV90eXBlIDwtIGFzLmZhY3Rvcih0ZXN0X2M1MCRwcmltYXJ5X3R5cGUpCgojQ3JlYXRpbmcgdGhlIGRlY2lzaW9uIHRyZWUgYWxnb3JpdGhtIEM0LjUgCnRyZWVfcmVzdWx0IDwtIEM1LjAoZGlzdHJpY3QgIH4gLiwgZGF0YT10cmFpbl9jNTAsIGNvbnRyb2wgPSBDNS4wQ29udHJvbChub0dsb2JhbFBydW5pbmcgPSBGQUxTRSwgQ0Y9IDAuMDAxKSkgICNIaWdoZXIgQ0YgbGVzcyBwcnVubmluZwpzdW1tYXJ5KHRyZWVfcmVzdWx0KQojUGxvdHRpbmcgdGhlIHRyZWUKcGxvdCh0cmVlX3Jlc3VsdCxzdWJ0cmVlPU5VTEwpCgojIyBQUkVESUNUSU9OCiNQcmVkaWN0aW9uIG9mIG5ldyBjYXNlcyBmcm9tIHRoZSB0ZXN0IGRhdGFzZXQKcHJlZGljdGlvbnMgPC0gcHJlZGljdCh0cmVlX3Jlc3VsdCwgbmV3ZGF0YSA9IHRlc3RfYzUwLCB0eXBlID0iY2xhc3MiKQoKI3RhYmxlKHByZWRpY3Rpb249cHJlZGljdGlvbnMsIHJlYWw9IGNyaW1lX3Rlc3RfYzUwJHByaW1hcnlfdHlwZSkKI2NyaW1lX3Rlc3RfYzUwJHByaW1hcnlfdHlwZSA8LSBmYWN0b3IoY3JpbWVfdGVzdF9jNTAkcHJpbWFyeV90eXBlKQplcnJvcl9jbGFzc2lmaWNhdGlvbiA8LSBtZWFuKHByZWRpY3Rpb25zICE9IHRlc3RfYzUwJGRpc3RyaWN0KQoKcGFzdGUoIlRoZSBjbGFzc2lmaWNhdGlvbiBlcnJvciBpbiB0ZXN0IHNldCBpczoiLCAxMDAqZXJyb3JfY2xhc3NpZmljYXRpb24sICIlIiwKICAgICAgc3VtKHByZWRpY3Rpb25zPT10ZXN0X2M1MCRkaXN0cmljdCksCiAgICAgICJjb3JyZWN0IGNsYXNzaWZpZWQgY2FzZXMgZnJvbSIsIGxlbmd0aChwcmVkaWN0aW9ucykpCgpwcmVkX3RyYWluIDwtIHByZWRpY3QodHJlZV9yZXN1bHQsIG5ld2RhdGEgPSB0cmFpbl9jNTApCiNjb25mdXNpb25NYXRyaXgocHJlZF90cmFpbiwgY3JpbWVfdHJhaW4kZGlzdHJpY3QpCiNwcmVkX3RyYWluPC1yb3VuZChwcmVkX3RyYWluKQojdGFibGUocHJlZGljdGlvbj1wcmVkX3RyYWluLCByZWFsPSBjcmltZV90cmFpbl9jNTAkYXJyZXN0KQoKZXJyb3JfY2xhc3NpZmljYXRpb24gPC0gbWVhbihwcmVkX3RyYWluICE9IHRyYWluX2M1MCRkaXN0cmljdCkKCnBhc3RlKCJUaGUgY2xhc3NpZmljYXRpb24gZXJyb3IgaW4gdHJhaW4gc2V0IGlzOiIsIDEwMCplcnJvcl9jbGFzc2lmaWNhdGlvbiwgIiUiLAogICAgICBzdW0ocHJlZF90cmFpbj09dHJhaW5fYzUwJGRpc3RyaWN0KSwKICAgICAgImNvcnJlY3QgY2xhc3NpZmllZCBjYXNlcyBmcm9tIiwgbGVuZ3RoKHByZWRfdHJhaW4pKQpgYGAKYGBge3J9CiNsZXZlbHMoY2hpY2Fnb19jcmltZSRsb2NhdGlvbl9kZXNjcmlwdGlvbilbMV0gPSAiTm9uZSIKIyMgQ3JlYXRpbmcgYSB0cmFpbmluZyBhbmQgdGVzdCBkYXRhc2V0cwpzZXQuc2VlZCgxMjM0KQojZGVjZXB0aXZlX3ByYWN0aWNlIDwtIHN1YnNldChkZWNlcHRpdmVfcHJhY3RpY2UsIHNlbGVjdD0tYyhsb2NhdGlvbl9kZXNjcmlwdGlvbikpCiNkZWNlcHRpdmVfcHJhY3RpY2VfdHIgPC0gc3Vic2V0KGRlY2VwdGl2ZV9wcmFjdGljZV90ciwgc2VsZWN0PS1jKGxvY2F0aW9uX2Rlc2NyaXB0aW9uKSkKCmRlY2VwdGl2ZV9wcmFjdGljZV90ciA8LSBzdWJzZXQoZGVjZXB0aXZlX3ByYWN0aWNlX3RyLCBkaXN0cmljdD09IjE5IiB8IGRpc3RyaWN0ID09ICI0IiB8IGRpc3RyaWN0ID09ICIyNSIgfCBkaXN0cmljdD09IjIiIHwgZGlzdHJpY3QgPT0gIjI0IiB8ZGlzdHJpY3QgPT0gIjEiIHwgZGlzdHJpY3QgPT0gIjE4InwgZGlzdHJpY3QgPT0gIjIwIiAgfCBkaXN0cmljdCA9PSAiOSIgfCBkaXN0cmljdD09IjIxIiB8IGRpc3RyaWN0ID09ICIyNSIgfCBkaXN0cmljdCA9PSAiMTEiICkKCmRlY2VwdGl2ZV9wcmFjdGljZSA8LSBzdWJzZXQoZGVjZXB0aXZlX3ByYWN0aWNlLCBkaXN0cmljdD09IjE5IiB8IGRpc3RyaWN0ID09ICI0IiB8IGRpc3RyaWN0ID09ICIyNSIgfCBkaXN0cmljdD09IjIiIHwgZGlzdHJpY3QgPT0gIjI0IiB8ZGlzdHJpY3QgPT0gIjEiIHwgZGlzdHJpY3QgPT0gIjE4InwgZGlzdHJpY3QgPT0gIjIwIiAgfCBkaXN0cmljdCA9PSAiOSIgfCBkaXN0cmljdD09IjIxIiB8IGRpc3RyaWN0ID09ICIyNSIgfCBkaXN0cmljdCA9PSAiMTEiICkKCiN0cmFpbl9jNTA8LSBzdWJzZXQoZGVjZXB0aXZlX3ByYWN0aWNlX3RyLCBzZWxlY3Q9LWMoY2FzZV9udW1iZXIsYmxvY2ssd2FyZCxkZXNjcmlwdGlvbixkYXksbW9udGgsbGF0aXR1ZGUsbG9uZ2l0dWRlKSkKI3Rlc3RfYzUwPC0gc3Vic2V0KGRlY2VwdGl2ZV9wcmFjdGljZSwgc2VsZWN0PS1jKGNhc2VfbnVtYmVyLGJsb2NrLHdhcmQsZGVzY3JpcHRpb24sZGF5LG1vbnRoLGxhdGl0dWRlLGxvbmdpdHVkZSkpCgpjcmltZV9zcGxpdF9jNTA8LSBpbml0aWFsX3NwbGl0KHN1YnNldChkZWNlcHRpdmVfcHJhY3RpY2VfdHIsIHNlbGVjdD0tYyhsb2NhdGlvbl9kZXNjcmlwdGlvbixjYXNlX251bWJlcixibG9jayx3YXJkLGRlc2NyaXB0aW9uLGRheSxtb250aCxsYXRpdHVkZSxsb25naXR1ZGUpKSwgcHJvcD0wLjgpCnRyYWluX2M1MDwtIHRyYWluaW5nKGNyaW1lX3NwbGl0X2M1MCkKdGVzdF9jNTA8LSB0ZXN0aW5nKGNyaW1lX3NwbGl0X2M1MCkKCiN0cmFpbl9jNTAkbG9jYXRpb25fZGVzY3JpcHRpb24gPC0gYXMuZmFjdG9yKHRyYWluX2M1MCRsb2NhdGlvbl9kZXNjcmlwdGlvbikKI3Rlc3RfYzUwJGxvY2F0aW9uX2Rlc2NyaXB0aW9uIDwtIGFzLmZhY3Rvcih0ZXN0X2M1MCRsb2NhdGlvbl9kZXNjcmlwdGlvbikKI3RyYWluX2M1MCRhcnJlc3QgPC0gYXMubnVtZXJpYyh0cmFpbl9jNTAkYXJyZXN0LCB1bmlxdWUodHJhaW5fYzUwJGFycmVzdCkpCiN0ZXN0X2M1MCRhcnJlc3QgPC0gYXMubnVtZXJpYyh0ZXN0X2M1MCRhcnJlc3QsIHVuaXF1ZSh0ZXN0X2M1MCRhcnJlc3QpKQojdHJhaW5fYzUwJHByaW1hcnlfdHlwZSA8LSBhcy5udW1lcmljKHRyYWluX2M1MCRwcmltYXJ5X3R5cGUsIHVuaXF1ZSh0cmFpbl9jNTAkcHJpbWFyeV90eXBlKSkKI3Rlc3RfYzUwJHByaW1hcnlfdHlwZSA8LSBhcy5udW1lcmljKHRlc3RfYzUwJHByaW1hcnlfdHlwZSwgdW5pcXVlKHRlc3RfYzUwJHByaW1hcnlfdHlwZSkpCiN0cmFpbl9jNTAkbG9jYXRpb25fZGVzY3JpcHRpb24gPC0gYXMubnVtZXJpYyh0cmFpbl9jNTAkbG9jYXRpb25fZGVzY3JpcHRpb24sIHVuaXF1ZSh0cmFpbl9jNTAkbG9jYXRpb25fZGVzY3JpcHRpb24pKQojdGVzdF9jNTAkbG9jYXRpb25fZGVzY3JpcHRpb24gPC0gYXMubnVtZXJpYyh0ZXN0X2M1MCRsb2NhdGlvbl9kZXNjcmlwdGlvbiwgdW5pcXVlKHRlc3RfYzUwJGxvY2F0aW9uX2Rlc2NyaXB0aW9uKSkKI3RyYWluX2M1MCRkaXN0cmljdCA8LSBhcy5udW1lcmljKHRyYWluX2M1MCRkaXN0cmljdCwgdW5pcXVlKHRyYWluX2M1MCRkaXN0cmljdCkpCiN0ZXN0X2M1MCRkaXN0cmljdCA8LSBhcy5udW1lcmljKHRlc3RfYzUwJGRpc3RyaWN0LCB1bmlxdWUodGVzdF9jNTAkZGlzdHJpY3QpKQp0cmFpbl9jNTAkYXJyZXN0IDwtIGFzLmZhY3Rvcih0cmFpbl9jNTAkYXJyZXN0KQp0ZXN0X2M1MCRhcnJlc3QgPC0gYXMuZmFjdG9yKHRlc3RfYzUwJGFycmVzdCkKdHJhaW5fYzUwJGRpc3RyaWN0IDwtIGFzLmZhY3Rvcih0cmFpbl9jNTAkZGlzdHJpY3QpCnRlc3RfYzUwJGRpc3RyaWN0IDwtIGFzLmZhY3Rvcih0ZXN0X2M1MCRkaXN0cmljdCkKdHJhaW5fYzUwJGRpc3RyaWN0IDwtIGZhY3Rvcih0cmFpbl9jNTAkZGlzdHJpY3QpCnRlc3RfYzUwJGRpc3RyaWN0IDwtIGZhY3Rvcih0ZXN0X2M1MCRkaXN0cmljdCkKI3RyYWluX2M1MCRwcmltYXJ5X3R5cGUgPC0gYXMuZmFjdG9yKHRyYWluX2M1MCRwcmltYXJ5X3R5cGUpCiN0ZXN0X2M1MCRwcmltYXJ5X3R5cGUgPC0gYXMuZmFjdG9yKHRlc3RfYzUwJHByaW1hcnlfdHlwZSkKCgojQ3JlYXRpbmcgdGhlIGRlY2lzaW9uIHRyZWUgYWxnb3JpdGhtIEM0LjUgCnRyZWVfcmVzdWx0IDwtIEM1LjAoZGlzdHJpY3QgIH4gLiwgZGF0YT10cmFpbl9jNTAsIGNvbnRyb2wgPSBDNS4wQ29udHJvbChub0dsb2JhbFBydW5pbmcgPSBGQUxTRSwgQ0Y9IDAuNSkpICAjSGlnaGVyIENGIGxlc3MgcHJ1bm5pbmcKI3N1bW1hcnkodHJlZV9yZXN1bHQpCiNQbG90dGluZyB0aGUgdHJlZQpwbG90KHRyZWVfcmVzdWx0LHN1YnRyZWU9TlVMTCkKCiMjIFBSRURJQ1RJT04KI1ByZWRpY3Rpb24gb2YgbmV3IGNhc2VzIGZyb20gdGhlIHRlc3QgZGF0YXNldApwcmVkaWN0aW9ucyA8LSBwcmVkaWN0KHRyZWVfcmVzdWx0LCBuZXdkYXRhID0gdGVzdF9jNTAsIHR5cGUgPSJjbGFzcyIpCgojdGFibGUocHJlZGljdGlvbj1wcmVkaWN0aW9ucywgcmVhbD0gY3JpbWVfdGVzdF9jNTAkcHJpbWFyeV90eXBlKQojY3JpbWVfdGVzdF9jNTAkcHJpbWFyeV90eXBlIDwtIGZhY3RvcihjcmltZV90ZXN0X2M1MCRwcmltYXJ5X3R5cGUpCmVycm9yX2NsYXNzaWZpY2F0aW9uIDwtIG1lYW4ocHJlZGljdGlvbnMgIT0gdGVzdF9jNTAkZGlzdHJpY3QpCgpwYXN0ZSgiVGhlIGNsYXNzaWZpY2F0aW9uIGVycm9yIGluIHRlc3Qgc2V0IGlzOiIsIDEwMCplcnJvcl9jbGFzc2lmaWNhdGlvbiwgIiUiLAogICAgICBzdW0ocHJlZGljdGlvbnM9PXRlc3RfYzUwJGRpc3RyaWN0KSwKICAgICAgImNvcnJlY3QgY2xhc3NpZmllZCBjYXNlcyBmcm9tIiwgbGVuZ3RoKHByZWRpY3Rpb25zKSkKCnByZWRfdHJhaW4gPC0gcHJlZGljdCh0cmVlX3Jlc3VsdCwgbmV3ZGF0YSA9IHRyYWluX2M1MCkKI2NvbmZ1c2lvbk1hdHJpeChwcmVkX3RyYWluLCBjcmltZV90cmFpbiRkaXN0cmljdCkKI3ByZWRfdHJhaW48LXJvdW5kKHByZWRfdHJhaW4pCiN0YWJsZShwcmVkaWN0aW9uPXByZWRfdHJhaW4sIHJlYWw9IGNyaW1lX3RyYWluX2M1MCRhcnJlc3QpCgplcnJvcl9jbGFzc2lmaWNhdGlvbiA8LSBtZWFuKHByZWRfdHJhaW4gIT0gdHJhaW5fYzUwJGRpc3RyaWN0KQoKcGFzdGUoIlRoZSBjbGFzc2lmaWNhdGlvbiBlcnJvciBpbiB0cmFpbiBzZXQgaXM6IiwgMTAwKmVycm9yX2NsYXNzaWZpY2F0aW9uLCAiJSIsCiAgICAgIHN1bShwcmVkX3RyYWluPT10cmFpbl9jNTAkZGlzdHJpY3QpLAogICAgICAiY29ycmVjdCBjbGFzc2lmaWVkIGNhc2VzIGZyb20iLCBsZW5ndGgocHJlZF90cmFpbikpCmBgYApgYGB7cn0KI2xldmVscyhjaGljYWdvX2NyaW1lJGxvY2F0aW9uX2Rlc2NyaXB0aW9uKVsxXSA9ICJOb25lIgojIyBDcmVhdGluZyBhIHRyYWluaW5nIGFuZCB0ZXN0IGRhdGFzZXRzCnNldC5zZWVkKDEyMzQpCiNuYXJjb3RpY3MgPC0gc3Vic2V0KG5hcmNvdGljcywgc2VsZWN0PS1jKGxvY2F0aW9uX2Rlc2NyaXB0aW9uKSkKI25hcmNvdGljc190ciA8LSBzdWJzZXQobmFyY290aWNzX3RyLCBzZWxlY3Q9LWMobG9jYXRpb25fZGVzY3JpcHRpb24pKQpuYXJjb3RpY3NfdHIgPC0gc3Vic2V0KG5hcmNvdGljc190ciwgZGlzdHJpY3Q9PSIxMCIgfCBkaXN0cmljdCA9PSAiMTEiIHwgZGlzdHJpY3QgPT0gIjE1IiB8IGRpc3RyaWN0PT0iOCIgfCBkaXN0cmljdCA9PSAiMSIgfCBkaXN0cmljdD09IjE4IikKbmFyY290aWNzIDwtIHN1YnNldChuYXJjb3RpY3MsIGRpc3RyaWN0PT0iMTAiIHwgZGlzdHJpY3QgPT0gIjExIiB8IGRpc3RyaWN0ID09ICIxNSIgfCBkaXN0cmljdD09IjgiIHwgZGlzdHJpY3QgPT0gIjEiIHwgZGlzdHJpY3Q9PSIxOCIpCgojdHJhaW5fYzUwPC0gc3Vic2V0KG5hcmNvdGljc190ciwgc2VsZWN0PS1jKGNhc2VfbnVtYmVyLGJsb2NrLHdhcmQsZGVzY3JpcHRpb24sZGF5LG1vbnRoLGxhdGl0dWRlLGxvbmdpdHVkZSkpCiN0ZXN0X2M1MDwtIHN1YnNldChuYXJjb3RpY3MsIHNlbGVjdD0tYyhjYXNlX251bWJlcixibG9jayx3YXJkLGRlc2NyaXB0aW9uLGRheSxtb250aCxsYXRpdHVkZSxsb25naXR1ZGUpKQoKY3JpbWVfc3BsaXRfYzUwPC0gaW5pdGlhbF9zcGxpdChzdWJzZXQobmFyY290aWNzX3RyLCBzZWxlY3Q9LWMobG9jYXRpb25fZGVzY3JpcHRpb24sY2FzZV9udW1iZXIsYmxvY2ssd2FyZCxkZXNjcmlwdGlvbixkYXksbW9udGgsbGF0aXR1ZGUsbG9uZ2l0dWRlKSksIHByb3A9MC44KQp0cmFpbl9jNTA8LSB0cmFpbmluZyhjcmltZV9zcGxpdF9jNTApCnRlc3RfYzUwPC0gdGVzdGluZyhjcmltZV9zcGxpdF9jNTApCgojdHJhaW5fYzUwJGxvY2F0aW9uX2Rlc2NyaXB0aW9uIDwtIGFzLmZhY3Rvcih0cmFpbl9jNTAkbG9jYXRpb25fZGVzY3JpcHRpb24pCiN0ZXN0X2M1MCRsb2NhdGlvbl9kZXNjcmlwdGlvbiA8LSBhcy5mYWN0b3IodGVzdF9jNTAkbG9jYXRpb25fZGVzY3JpcHRpb24pCiN0cmFpbl9jNTAkYXJyZXN0IDwtIGFzLm51bWVyaWModHJhaW5fYzUwJGFycmVzdCwgdW5pcXVlKHRyYWluX2M1MCRhcnJlc3QpKQojdGVzdF9jNTAkYXJyZXN0IDwtIGFzLm51bWVyaWModGVzdF9jNTAkYXJyZXN0LCB1bmlxdWUodGVzdF9jNTAkYXJyZXN0KSkKI3RyYWluX2M1MCRwcmltYXJ5X3R5cGUgPC0gYXMubnVtZXJpYyh0cmFpbl9jNTAkcHJpbWFyeV90eXBlLCB1bmlxdWUodHJhaW5fYzUwJHByaW1hcnlfdHlwZSkpCiN0ZXN0X2M1MCRwcmltYXJ5X3R5cGUgPC0gYXMubnVtZXJpYyh0ZXN0X2M1MCRwcmltYXJ5X3R5cGUsIHVuaXF1ZSh0ZXN0X2M1MCRwcmltYXJ5X3R5cGUpKQojdHJhaW5fYzUwJGxvY2F0aW9uX2Rlc2NyaXB0aW9uIDwtIGFzLm51bWVyaWModHJhaW5fYzUwJGxvY2F0aW9uX2Rlc2NyaXB0aW9uLCB1bmlxdWUodHJhaW5fYzUwJGxvY2F0aW9uX2Rlc2NyaXB0aW9uKSkKI3Rlc3RfYzUwJGxvY2F0aW9uX2Rlc2NyaXB0aW9uIDwtIGFzLm51bWVyaWModGVzdF9jNTAkbG9jYXRpb25fZGVzY3JpcHRpb24sIHVuaXF1ZSh0ZXN0X2M1MCRsb2NhdGlvbl9kZXNjcmlwdGlvbikpCiN0cmFpbl9jNTAkZGlzdHJpY3QgPC0gYXMubnVtZXJpYyh0cmFpbl9jNTAkZGlzdHJpY3QsIHVuaXF1ZSh0cmFpbl9jNTAkZGlzdHJpY3QpKQojdGVzdF9jNTAkZGlzdHJpY3QgPC0gYXMubnVtZXJpYyh0ZXN0X2M1MCRkaXN0cmljdCwgdW5pcXVlKHRlc3RfYzUwJGRpc3RyaWN0KSkKI3RyYWluX2M1MCRhcnJlc3QgPC0gYXMuZmFjdG9yKHRyYWluX2M1MCRhcnJlc3QpCiN0ZXN0X2M1MCRhcnJlc3QgPC0gYXMuZmFjdG9yKHRlc3RfYzUwJGFycmVzdCkKdHJhaW5fYzUwJGRpc3RyaWN0IDwtIGFzLmZhY3Rvcih0cmFpbl9jNTAkZGlzdHJpY3QpCnRlc3RfYzUwJGRpc3RyaWN0IDwtIGFzLmZhY3Rvcih0ZXN0X2M1MCRkaXN0cmljdCkKdHJhaW5fYzUwJGRpc3RyaWN0IDwtIGZhY3Rvcih0cmFpbl9jNTAkZGlzdHJpY3QpCnRlc3RfYzUwJGRpc3RyaWN0IDwtIGZhY3Rvcih0ZXN0X2M1MCRkaXN0cmljdCkKI3RyYWluX2M1MCRwcmltYXJ5X3R5cGUgPC0gYXMuZmFjdG9yKHRyYWluX2M1MCRwcmltYXJ5X3R5cGUpCiN0ZXN0X2M1MCRwcmltYXJ5X3R5cGUgPC0gYXMuZmFjdG9yKHRlc3RfYzUwJHByaW1hcnlfdHlwZSkKCgojQ3JlYXRpbmcgdGhlIGRlY2lzaW9uIHRyZWUgYWxnb3JpdGhtIEM0LjUgCnRyZWVfcmVzdWx0IDwtIEM1LjAoZGlzdHJpY3QgIH4gLiwgZGF0YT10cmFpbl9jNTAsIGNvbnRyb2wgPSBDNS4wQ29udHJvbChub0dsb2JhbFBydW5pbmcgPSBGQUxTRSwgQ0Y9IDAuMDEpKSAgI0hpZ2hlciBDRiBsZXNzIHBydW5uaW5nCnN1bW1hcnkodHJlZV9yZXN1bHQpCiNQbG90dGluZyB0aGUgdHJlZQpwbG90KHRyZWVfcmVzdWx0LHN1YnRyZWU9TlVMTCkKCiMjIFBSRURJQ1RJT04KI1ByZWRpY3Rpb24gb2YgbmV3IGNhc2VzIGZyb20gdGhlIHRlc3QgZGF0YXNldApwcmVkaWN0aW9ucyA8LSBwcmVkaWN0KHRyZWVfcmVzdWx0LCBuZXdkYXRhID0gdGVzdF9jNTAsIHR5cGUgPSJjbGFzcyIpCgojdGFibGUocHJlZGljdGlvbj1wcmVkaWN0aW9ucywgcmVhbD0gY3JpbWVfdGVzdF9jNTAkcHJpbWFyeV90eXBlKQojY3JpbWVfdGVzdF9jNTAkcHJpbWFyeV90eXBlIDwtIGZhY3RvcihjcmltZV90ZXN0X2M1MCRwcmltYXJ5X3R5cGUpCmVycm9yX2NsYXNzaWZpY2F0aW9uIDwtIG1lYW4ocHJlZGljdGlvbnMgIT0gdGVzdF9jNTAkZGlzdHJpY3QpCgpwYXN0ZSgiVGhlIGNsYXNzaWZpY2F0aW9uIGVycm9yIGluIHRlc3Qgc2V0IGlzOiIsIDEwMCplcnJvcl9jbGFzc2lmaWNhdGlvbiwgIiUiLAogICAgICBzdW0ocHJlZGljdGlvbnM9PXRlc3RfYzUwJGRpc3RyaWN0KSwKICAgICAgImNvcnJlY3QgY2xhc3NpZmllZCBjYXNlcyBmcm9tIiwgbGVuZ3RoKHByZWRpY3Rpb25zKSkKCnByZWRfdHJhaW4gPC0gcHJlZGljdCh0cmVlX3Jlc3VsdCwgbmV3ZGF0YSA9IHRyYWluX2M1MCkKI2NvbmZ1c2lvbk1hdHJpeChwcmVkX3RyYWluLCBjcmltZV90cmFpbiRkaXN0cmljdCkKI3ByZWRfdHJhaW48LXJvdW5kKHByZWRfdHJhaW4pCiN0YWJsZShwcmVkaWN0aW9uPXByZWRfdHJhaW4sIHJlYWw9IGNyaW1lX3RyYWluX2M1MCRhcnJlc3QpCgplcnJvcl9jbGFzc2lmaWNhdGlvbiA8LSBtZWFuKHByZWRfdHJhaW4gIT0gdHJhaW5fYzUwJGRpc3RyaWN0KQoKcGFzdGUoIlRoZSBjbGFzc2lmaWNhdGlvbiBlcnJvciBpbiB0cmFpbiBzZXQgaXM6IiwgMTAwKmVycm9yX2NsYXNzaWZpY2F0aW9uLCAiJSIsCiAgICAgIHN1bShwcmVkX3RyYWluPT10cmFpbl9jNTAkZGlzdHJpY3QpLAogICAgICAiY29ycmVjdCBjbGFzc2lmaWVkIGNhc2VzIGZyb20iLCBsZW5ndGgocHJlZF90cmFpbikpCmBgYApgYGB7cn0KIyMgQ3JlYXRpbmcgYSB0cmFpbmluZyBhbmQgdGVzdCBkYXRhc2V0cwpzZXQuc2VlZCgxMjM0KQojcm9iYmVyeSA8LSBzdWJzZXQocm9iYmVyeSwgc2VsZWN0PS1jKGxvY2F0aW9uX2Rlc2NyaXB0aW9uKSkKI3JvYmJlcnlfdHIgPC0gc3Vic2V0KHJvYmJlcnlfdHIsIHNlbGVjdD0tYyhsb2NhdGlvbl9kZXNjcmlwdGlvbikpCnJvYmJlcnlfdHIgPC0gc3Vic2V0KHJvYmJlcnlfdHIsIGRpc3RyaWN0PT0iNiIgfCBkaXN0cmljdCA9PSAiMTEiIHwgZGlzdHJpY3QgPT0gIjE1IiB8IGRpc3RyaWN0PT0iOCIgfCBkaXN0cmljdCA9PSAiMSIgfCBkaXN0cmljdD09IjE4InwgZGlzdHJpY3Q9PSI5IiB8IGRpc3RyaWN0ID09ICI1IiB8IGRpc3RyaWN0PT0iNCIpCnJvYmJlcnkgPC0gc3Vic2V0KHJvYmJlcnksIGRpc3RyaWN0PT0iNiIgfCBkaXN0cmljdCA9PSAiMTEiIHwgZGlzdHJpY3QgPT0gIjE1IiB8IGRpc3RyaWN0PT0iOCIgfCBkaXN0cmljdCA9PSAiMSIgfCBkaXN0cmljdD09IjE4InwgZGlzdHJpY3Q9PSI5IiB8IGRpc3RyaWN0ID09ICI1IiB8IGRpc3RyaWN0PT0iNCIpCgojcm9iYmVyeSRsb2NhdGlvbl9kZXNjcmlwdGlvbiA8LSBnc3ViKCJQQVJLSU5HIExPVCIsIlBBUktJTkciLHJvYmJlcnkkbG9jYXRpb25fZGVzY3JpcHRpb24pCiNyb2JiZXJ5X3RyJGxvY2F0aW9uX2Rlc2NyaXB0aW9uIDwtIGdzdWIoIlBBUktJTkcgTE9UIiwiUEFSS0lORyIscm9iYmVyeV90ciRsb2NhdGlvbl9kZXNjcmlwdGlvbikKI3JvYmJlcnkkbG9jYXRpb25fZGVzY3JpcHRpb24gPC0gZ3N1YigiUEFSS0lOR0dBUkFHRShOT04uUkVTSUQuKSIsIlBBUktJTkciLHJvYmJlcnkkbG9jYXRpb25fZGVzY3JpcHRpb24pCiNyb2JiZXJ5X3RyJGxvY2F0aW9uX2Rlc2NyaXB0aW9uIDwtIGdzdWIoIlBBUktJTkdHQVJBR0UoTk9OLlJFU0lELikiLCJQQVJLSU5HIixyb2JiZXJ5X3RyJGxvY2F0aW9uX2Rlc2NyaXB0aW9uKQoKdHJhaW5fYzUwPC0gc3Vic2V0KHJvYmJlcnlfdHIsIHNlbGVjdD0tYyhjYXNlX251bWJlcixibG9jayx3YXJkLGRlc2NyaXB0aW9uLGRheSxtb250aCxsYXRpdHVkZSxsb25naXR1ZGUpKQp0ZXN0X2M1MDwtIHN1YnNldChyb2JiZXJ5LCBzZWxlY3Q9LWMoY2FzZV9udW1iZXIsYmxvY2ssd2FyZCxkZXNjcmlwdGlvbixkYXksbW9udGgsbGF0aXR1ZGUsbG9uZ2l0dWRlKSkKCiNjcmltZV9zcGxpdF9jNTA8LSBpbml0aWFsX3NwbGl0KHN1YnNldChjaGljYWdvX2NyaW1lX3N1YnNldF90ciwgc2VsZWN0PS1jKGNhc2VfbnVtYmVyLGJsb2NrLHdhcmQsZGVzY3JpcHRpb24sZGF5LG1vbnRoLGxhdGl0dWRlLGxvbmdpdHVkZSkpLCBwcm9wPTAuOCkKI3RyYWluX2M1MDwtIHRyYWluaW5nKGNyaW1lX3NwbGl0X2M1MCkKI3Rlc3RfYzUwPC0gdGVzdGluZyhjcmltZV9zcGxpdF9jNTApCgp0cmFpbl9jNTAkbG9jYXRpb25fZGVzY3JpcHRpb24gPC0gYXMuZmFjdG9yKHRyYWluX2M1MCRsb2NhdGlvbl9kZXNjcmlwdGlvbikKdGVzdF9jNTAkbG9jYXRpb25fZGVzY3JpcHRpb24gPC0gYXMuZmFjdG9yKHRlc3RfYzUwJGxvY2F0aW9uX2Rlc2NyaXB0aW9uKQp0cmFpbl9jNTAkbG9jYXRpb25fZGVzY3JpcHRpb24gPC0gZmFjdG9yKHRyYWluX2M1MCRsb2NhdGlvbl9kZXNjcmlwdGlvbikKdGVzdF9jNTAkbG9jYXRpb25fZGVzY3JpcHRpb24gPC0gZmFjdG9yKHRlc3RfYzUwJGxvY2F0aW9uX2Rlc2NyaXB0aW9uKQojdHJhaW5fYzUwJGFycmVzdCA8LSBhcy5udW1lcmljKHRyYWluX2M1MCRhcnJlc3QsIHVuaXF1ZSh0cmFpbl9jNTAkYXJyZXN0KSkKI3Rlc3RfYzUwJGFycmVzdCA8LSBhcy5udW1lcmljKHRlc3RfYzUwJGFycmVzdCwgdW5pcXVlKHRlc3RfYzUwJGFycmVzdCkpCiN0cmFpbl9jNTAkcHJpbWFyeV90eXBlIDwtIGFzLm51bWVyaWModHJhaW5fYzUwJHByaW1hcnlfdHlwZSwgdW5pcXVlKHRyYWluX2M1MCRwcmltYXJ5X3R5cGUpKQojdGVzdF9jNTAkcHJpbWFyeV90eXBlIDwtIGFzLm51bWVyaWModGVzdF9jNTAkcHJpbWFyeV90eXBlLCB1bmlxdWUodGVzdF9jNTAkcHJpbWFyeV90eXBlKSkKdHJhaW5fYzUwJGxvY2F0aW9uX2Rlc2NyaXB0aW9uIDwtIGFzLm51bWVyaWModHJhaW5fYzUwJGxvY2F0aW9uX2Rlc2NyaXB0aW9uLCB1bmlxdWUodHJhaW5fYzUwJGxvY2F0aW9uX2Rlc2NyaXB0aW9uKSkKdGVzdF9jNTAkbG9jYXRpb25fZGVzY3JpcHRpb24gPC0gYXMubnVtZXJpYyh0ZXN0X2M1MCRsb2NhdGlvbl9kZXNjcmlwdGlvbiwgdW5pcXVlKHRlc3RfYzUwJGxvY2F0aW9uX2Rlc2NyaXB0aW9uKSkKI3RyYWluX2M1MCRkaXN0cmljdCA8LSBhcy5udW1lcmljKHRyYWluX2M1MCRkaXN0cmljdCwgdW5pcXVlKHRyYWluX2M1MCRkaXN0cmljdCkpCiN0ZXN0X2M1MCRkaXN0cmljdCA8LSBhcy5udW1lcmljKHRlc3RfYzUwJGRpc3RyaWN0LCB1bmlxdWUodGVzdF9jNTAkZGlzdHJpY3QpKQp0cmFpbl9jNTAkYXJyZXN0IDwtIGFzLmZhY3Rvcih0cmFpbl9jNTAkYXJyZXN0KQp0ZXN0X2M1MCRhcnJlc3QgPC0gYXMuZmFjdG9yKHRlc3RfYzUwJGFycmVzdCkKdHJhaW5fYzUwJGRpc3RyaWN0IDwtIGFzLmZhY3Rvcih0cmFpbl9jNTAkZGlzdHJpY3QpCnRlc3RfYzUwJGRpc3RyaWN0IDwtIGFzLmZhY3Rvcih0ZXN0X2M1MCRkaXN0cmljdCkKdHJhaW5fYzUwJGRpc3RyaWN0IDwtIGZhY3Rvcih0cmFpbl9jNTAkZGlzdHJpY3QpCnRlc3RfYzUwJGRpc3RyaWN0IDwtIGZhY3Rvcih0ZXN0X2M1MCRkaXN0cmljdCkKI3RyYWluX2M1MCRwcmltYXJ5X3R5cGUgPC0gYXMuZmFjdG9yKHRyYWluX2M1MCRwcmltYXJ5X3R5cGUpCiN0ZXN0X2M1MCRwcmltYXJ5X3R5cGUgPC0gYXMuZmFjdG9yKHRlc3RfYzUwJHByaW1hcnlfdHlwZSkKCgojQ3JlYXRpbmcgdGhlIGRlY2lzaW9uIHRyZWUgYWxnb3JpdGhtIEM0LjUgCnRyZWVfcmVzdWx0IDwtIEM1LjAoZGlzdHJpY3QgIH4uLCBkYXRhPXRyYWluX2M1MCwgY29udHJvbCA9IEM1LjBDb250cm9sKG5vR2xvYmFsUHJ1bmluZyA9IFRSVUUsIENGPSAwLjAwMDAwMSkpICAjSGlnaGVyIENGIGxlc3MgcHJ1bm5pbmcKc3VtbWFyeSh0cmVlX3Jlc3VsdCkKI1Bsb3R0aW5nIHRoZSB0cmVlCnBsb3QodHJlZV9yZXN1bHQsc3VidHJlZT1OVUxMKQoKIyMgUFJFRElDVElPTgojUHJlZGljdGlvbiBvZiBuZXcgY2FzZXMgZnJvbSB0aGUgdGVzdCBkYXRhc2V0CnByZWRpY3Rpb25zIDwtIHByZWRpY3QodHJlZV9yZXN1bHQsIG5ld2RhdGEgPSB0ZXN0X2M1MCwgdHlwZSA9ImNsYXNzIikKCiN0YWJsZShwcmVkaWN0aW9uPXByZWRpY3Rpb25zLCByZWFsPSBjcmltZV90ZXN0X2M1MCRwcmltYXJ5X3R5cGUpCiNjcmltZV90ZXN0X2M1MCRwcmltYXJ5X3R5cGUgPC0gZmFjdG9yKGNyaW1lX3Rlc3RfYzUwJHByaW1hcnlfdHlwZSkKZXJyb3JfY2xhc3NpZmljYXRpb24gPC0gbWVhbihwcmVkaWN0aW9ucyAhPSB0ZXN0X2M1MCRkaXN0cmljdCkKCnBhc3RlKCJUaGUgY2xhc3NpZmljYXRpb24gZXJyb3IgaW4gdGVzdCBzZXQgaXM6IiwgMTAwKmVycm9yX2NsYXNzaWZpY2F0aW9uLCAiJSIsCiAgICAgIHN1bShwcmVkaWN0aW9ucz09dGVzdF9jNTAkZGlzdHJpY3QpLAogICAgICAiY29ycmVjdCBjbGFzc2lmaWVkIGNhc2VzIGZyb20iLCBsZW5ndGgocHJlZGljdGlvbnMpKQoKcHJlZF90cmFpbiA8LSBwcmVkaWN0KHRyZWVfcmVzdWx0LCBuZXdkYXRhID0gdHJhaW5fYzUwKQojY29uZnVzaW9uTWF0cml4KHByZWRfdHJhaW4sIGNyaW1lX3RyYWluJGRpc3RyaWN0KQojcHJlZF90cmFpbjwtcm91bmQocHJlZF90cmFpbikKI3RhYmxlKHByZWRpY3Rpb249cHJlZF90cmFpbiwgcmVhbD0gY3JpbWVfdHJhaW5fYzUwJGFycmVzdCkKCmVycm9yX2NsYXNzaWZpY2F0aW9uIDwtIG1lYW4ocHJlZF90cmFpbiAhPSB0cmFpbl9jNTAkZGlzdHJpY3QpCgpwYXN0ZSgiVGhlIGNsYXNzaWZpY2F0aW9uIGVycm9yIGluIHRyYWluIHNldCBpczoiLCAxMDAqZXJyb3JfY2xhc3NpZmljYXRpb24sICIlIiwKICAgICAgc3VtKHByZWRfdHJhaW49PXRyYWluX2M1MCRkaXN0cmljdCksCiAgICAgICJjb3JyZWN0IGNsYXNzaWZpZWQgY2FzZXMgZnJvbSIsIGxlbmd0aChwcmVkX3RyYWluKSkKYGBgCmBgYHtyfQojIyBDcmVhdGluZyBhIHRyYWluaW5nIGFuZCB0ZXN0IGRhdGFzZXRzCnNldC5zZWVkKDEyMzQpCnRoZWZ0IDwtIHN1YnNldCh0aGVmdCwgc2VsZWN0PS1jKGxvY2F0aW9uX2Rlc2NyaXB0aW9uKSkKdGhlZnRfdHIgPC0gc3Vic2V0KHRoZWZ0X3RyLCBzZWxlY3Q9LWMobG9jYXRpb25fZGVzY3JpcHRpb24pKQp0aGVmdF90ciA8LSBzdWJzZXQodGhlZnRfdHIsIGRpc3RyaWN0PT0iMTkiIHwgZGlzdHJpY3QgPT0gIjEiIHwgZGlzdHJpY3Q9PSIxOCJ8IGRpc3RyaWN0PT0iMjQiIHwgZGlzdHJpY3QgPT0gIjUiIHwgZGlzdHJpY3Q9PSI0IikKdGhlZnQgPC0gc3Vic2V0KHRoZWZ0LCBkaXN0cmljdD09IjE5IiB8IGRpc3RyaWN0ID09ICIxIiB8IGRpc3RyaWN0PT0iMTgifCBkaXN0cmljdD09IjI0IiB8IGRpc3RyaWN0ID09ICI1IiB8IGRpc3RyaWN0PT0iNCIpCgp0cmFpbl9jNTA8LSBzdWJzZXQodGhlZnRfdHIsIHNlbGVjdD0tYyhjYXNlX251bWJlcixibG9jayx3YXJkLGRlc2NyaXB0aW9uLGRheSxtb250aCxsYXRpdHVkZSxsb25naXR1ZGUpKQp0ZXN0X2M1MDwtIHN1YnNldCh0aGVmdCwgc2VsZWN0PS1jKGNhc2VfbnVtYmVyLGJsb2NrLHdhcmQsZGVzY3JpcHRpb24sZGF5LG1vbnRoLGxhdGl0dWRlLGxvbmdpdHVkZSkpCgojY3JpbWVfc3BsaXRfYzUwPC0gaW5pdGlhbF9zcGxpdChzdWJzZXQoY2hpY2Fnb19jcmltZV9zdWJzZXRfdHIsIHNlbGVjdD0tYyhjYXNlX251bWJlcixibG9jayx3YXJkLGRlc2NyaXB0aW9uLGRheSxtb250aCxsYXRpdHVkZSxsb25naXR1ZGUpKSwgcHJvcD0wLjgpCiN0cmFpbl9jNTA8LSB0cmFpbmluZyhjcmltZV9zcGxpdF9jNTApCiN0ZXN0X2M1MDwtIHRlc3RpbmcoY3JpbWVfc3BsaXRfYzUwKQoKdHJhaW5fYzUwJGxvY2F0aW9uX2Rlc2NyaXB0aW9uIDwtIGFzLmZhY3Rvcih0cmFpbl9jNTAkbG9jYXRpb25fZGVzY3JpcHRpb24pCnRlc3RfYzUwJGxvY2F0aW9uX2Rlc2NyaXB0aW9uIDwtIGFzLmZhY3Rvcih0ZXN0X2M1MCRsb2NhdGlvbl9kZXNjcmlwdGlvbikKI3RyYWluX2M1MCRhcnJlc3QgPC0gYXMubnVtZXJpYyh0cmFpbl9jNTAkYXJyZXN0LCB1bmlxdWUodHJhaW5fYzUwJGFycmVzdCkpCiN0ZXN0X2M1MCRhcnJlc3QgPC0gYXMubnVtZXJpYyh0ZXN0X2M1MCRhcnJlc3QsIHVuaXF1ZSh0ZXN0X2M1MCRhcnJlc3QpKQojdHJhaW5fYzUwJHByaW1hcnlfdHlwZSA8LSBhcy5udW1lcmljKHRyYWluX2M1MCRwcmltYXJ5X3R5cGUsIHVuaXF1ZSh0cmFpbl9jNTAkcHJpbWFyeV90eXBlKSkKI3Rlc3RfYzUwJHByaW1hcnlfdHlwZSA8LSBhcy5udW1lcmljKHRlc3RfYzUwJHByaW1hcnlfdHlwZSwgdW5pcXVlKHRlc3RfYzUwJHByaW1hcnlfdHlwZSkpCnRyYWluX2M1MCRsb2NhdGlvbl9kZXNjcmlwdGlvbiA8LSBhcy5udW1lcmljKHRyYWluX2M1MCRsb2NhdGlvbl9kZXNjcmlwdGlvbiwgdW5pcXVlKHRyYWluX2M1MCRsb2NhdGlvbl9kZXNjcmlwdGlvbikpCnRlc3RfYzUwJGxvY2F0aW9uX2Rlc2NyaXB0aW9uIDwtIGFzLm51bWVyaWModGVzdF9jNTAkbG9jYXRpb25fZGVzY3JpcHRpb24sIHVuaXF1ZSh0ZXN0X2M1MCRsb2NhdGlvbl9kZXNjcmlwdGlvbikpCiN0cmFpbl9jNTAkZGlzdHJpY3QgPC0gYXMubnVtZXJpYyh0cmFpbl9jNTAkZGlzdHJpY3QsIHVuaXF1ZSh0cmFpbl9jNTAkZGlzdHJpY3QpKQojdGVzdF9jNTAkZGlzdHJpY3QgPC0gYXMubnVtZXJpYyh0ZXN0X2M1MCRkaXN0cmljdCwgdW5pcXVlKHRlc3RfYzUwJGRpc3RyaWN0KSkKI3RyYWluX2M1MCRhcnJlc3QgPC0gYXMuZmFjdG9yKHRyYWluX2M1MCRhcnJlc3QpCiN0ZXN0X2M1MCRhcnJlc3QgPC0gYXMuZmFjdG9yKHRlc3RfYzUwJGFycmVzdCkKdHJhaW5fYzUwJGRpc3RyaWN0IDwtIGFzLmZhY3Rvcih0cmFpbl9jNTAkZGlzdHJpY3QpCnRlc3RfYzUwJGRpc3RyaWN0IDwtIGFzLmZhY3Rvcih0ZXN0X2M1MCRkaXN0cmljdCkKdHJhaW5fYzUwJGRpc3RyaWN0IDwtIGZhY3Rvcih0cmFpbl9jNTAkZGlzdHJpY3QpCnRlc3RfYzUwJGRpc3RyaWN0IDwtIGZhY3Rvcih0ZXN0X2M1MCRkaXN0cmljdCkKI3RyYWluX2M1MCRwcmltYXJ5X3R5cGUgPC0gYXMuZmFjdG9yKHRyYWluX2M1MCRwcmltYXJ5X3R5cGUpCiN0ZXN0X2M1MCRwcmltYXJ5X3R5cGUgPC0gYXMuZmFjdG9yKHRlc3RfYzUwJHByaW1hcnlfdHlwZSkKCgojQ3JlYXRpbmcgdGhlIGRlY2lzaW9uIHRyZWUgYWxnb3JpdGhtIEM0LjUgCnRyZWVfcmVzdWx0IDwtIEM1LjAoZGlzdHJpY3QgIH4gLiwgZGF0YT10cmFpbl9jNTAsIGNvbnRyb2wgPSBDNS4wQ29udHJvbChub0dsb2JhbFBydW5pbmcgPSBGQUxTRSwgQ0Y9IDAuMDEpKSAgI0hpZ2hlciBDRiBsZXNzIHBydW5uaW5nCiNzdW1tYXJ5KHRyZWVfcmVzdWx0KQojUGxvdHRpbmcgdGhlIHRyZWUKcGxvdCh0cmVlX3Jlc3VsdCxzdWJ0cmVlPU5VTEwpCgojIyBQUkVESUNUSU9OCiNQcmVkaWN0aW9uIG9mIG5ldyBjYXNlcyBmcm9tIHRoZSB0ZXN0IGRhdGFzZXQKcHJlZGljdGlvbnMgPC0gcHJlZGljdCh0cmVlX3Jlc3VsdCwgbmV3ZGF0YSA9IHRlc3RfYzUwLCB0eXBlID0iY2xhc3MiKQoKI3RhYmxlKHByZWRpY3Rpb249cHJlZGljdGlvbnMsIHJlYWw9IGNyaW1lX3Rlc3RfYzUwJHByaW1hcnlfdHlwZSkKI2NyaW1lX3Rlc3RfYzUwJHByaW1hcnlfdHlwZSA8LSBmYWN0b3IoY3JpbWVfdGVzdF9jNTAkcHJpbWFyeV90eXBlKQplcnJvcl9jbGFzc2lmaWNhdGlvbiA8LSBtZWFuKHByZWRpY3Rpb25zICE9IHRlc3RfYzUwJGRpc3RyaWN0KQoKcGFzdGUoIlRoZSBjbGFzc2lmaWNhdGlvbiBlcnJvciBpbiB0ZXN0IHNldCBpczoiLCAxMDAqZXJyb3JfY2xhc3NpZmljYXRpb24sICIlIiwKICAgICAgc3VtKHByZWRpY3Rpb25zPT10ZXN0X2M1MCRkaXN0cmljdCksCiAgICAgICJjb3JyZWN0IGNsYXNzaWZpZWQgY2FzZXMgZnJvbSIsIGxlbmd0aChwcmVkaWN0aW9ucykpCgpwcmVkX3RyYWluIDwtIHByZWRpY3QodHJlZV9yZXN1bHQsIG5ld2RhdGEgPSB0cmFpbl9jNTApCiNjb25mdXNpb25NYXRyaXgocHJlZF90cmFpbiwgY3JpbWVfdHJhaW4kZGlzdHJpY3QpCiNwcmVkX3RyYWluPC1yb3VuZChwcmVkX3RyYWluKQojdGFibGUocHJlZGljdGlvbj1wcmVkX3RyYWluLCByZWFsPSBjcmltZV90cmFpbl9jNTAkYXJyZXN0KQoKZXJyb3JfY2xhc3NpZmljYXRpb24gPC0gbWVhbihwcmVkX3RyYWluICE9IHRyYWluX2M1MCRkaXN0cmljdCkKCnBhc3RlKCJUaGUgY2xhc3NpZmljYXRpb24gZXJyb3IgaW4gdHJhaW4gc2V0IGlzOiIsIDEwMCplcnJvcl9jbGFzc2lmaWNhdGlvbiwgIiUiLAogICAgICBzdW0ocHJlZF90cmFpbj09dHJhaW5fYzUwJGRpc3RyaWN0KSwKICAgICAgImNvcnJlY3QgY2xhc3NpZmllZCBjYXNlcyBmcm9tIiwgbGVuZ3RoKHByZWRfdHJhaW4pKQpgYGAKYGBge3J9CnNldC5zZWVkKDEyMzQpCiN2aW9sZW50X2NyaW1lIDwtIHN1YnNldCh2aW9sZW50X2NyaW1lLCBzZWxlY3Q9LWMobG9jYXRpb25fZGVzY3JpcHRpb24pKQojdmlvbGVudF90cl9jcmltZSA8LSBzdWJzZXQodmlvbGVudF90cl9jcmltZSwgc2VsZWN0PS1jKGxvY2F0aW9uX2Rlc2NyaXB0aW9uKSkKdmlvbGVudF90cl9jcmltZSA8LSBzdWJzZXQodmlvbGVudF90cl9jcmltZSwgZGlzdHJpY3Q9PSI2IiB8IGRpc3RyaWN0ID09ICIxMSIgfCBkaXN0cmljdCA9PSAiMTUiIHwgZGlzdHJpY3Q9PSI4IiB8IGRpc3RyaWN0ID09ICIxIiB8IGRpc3RyaWN0PT0iMTgifCBkaXN0cmljdD09IjkiIHwgZGlzdHJpY3QgPT0gIjUiIHwgZGlzdHJpY3Q9PSI0IiB8IGRpc3RyaWN0ID09ICIxOSJ8IGRpc3RyaWN0ID09ICIyMCIgIHwgZGlzdHJpY3QgPT0gIjEwIiB8IGRpc3RyaWN0PT0iMjEiIHwgZGlzdHJpY3QgPT0gIjI1IiB8IGRpc3RyaWN0ID09ICIyIikKdmlvbGVudF9jcmltZSA8LSBzdWJzZXQodmlvbGVudF9jcmltZSwgZGlzdHJpY3Q9PSI2IiB8IGRpc3RyaWN0ID09ICIxMSIgfCBkaXN0cmljdCA9PSAiMTUiIHwgZGlzdHJpY3Q9PSI4IiB8IGRpc3RyaWN0ID09ICIxIiB8IGRpc3RyaWN0PT0iMTgifCBkaXN0cmljdD09IjkiIHwgZGlzdHJpY3QgPT0gIjUiIHwgZGlzdHJpY3Q9PSI0IiB8IGRpc3RyaWN0ID09ICIxOSJ8IGRpc3RyaWN0ID09ICIyMCIgIHwgZGlzdHJpY3QgPT0gIjEwIiB8IGRpc3RyaWN0PT0iMjEiIHwgZGlzdHJpY3QgPT0gIjI1IiB8IGRpc3RyaWN0ID09ICIyIikKCnRyYWluX2M1MDwtIHN1YnNldCh2aW9sZW50X3RyX2NyaW1lLCBzZWxlY3Q9LWMoY2FzZV9udW1iZXIsYmxvY2ssd2FyZCxkZXNjcmlwdGlvbixkYXksbW9udGgsbGF0aXR1ZGUsbG9uZ2l0dWRlKSkKdGVzdF9jNTA8LSBzdWJzZXQodmlvbGVudF9jcmltZSwgc2VsZWN0PS1jKGNhc2VfbnVtYmVyLGJsb2NrLHdhcmQsZGVzY3JpcHRpb24sZGF5LG1vbnRoLGxhdGl0dWRlLGxvbmdpdHVkZSkpCgojY3JpbWVfc3BsaXRfYzUwPC0gaW5pdGlhbF9zcGxpdChzdWJzZXQoY2hpY2Fnb19jcmltZV9zdWJzZXRfdHIsIHNlbGVjdD0tYyhjYXNlX251bWJlcixibG9jayx3YXJkLGRlc2NyaXB0aW9uLGRheSxtb250aCxsYXRpdHVkZSxsb25naXR1ZGUpKSwgcHJvcD0wLjgpCiN0cmFpbl9jNTA8LSB0cmFpbmluZyhjcmltZV9zcGxpdF9jNTApCiN0ZXN0X2M1MDwtIHRlc3RpbmcoY3JpbWVfc3BsaXRfYzUwKQoKdHJhaW5fYzUwJGxvY2F0aW9uX2Rlc2NyaXB0aW9uIDwtIGFzLmZhY3Rvcih0cmFpbl9jNTAkbG9jYXRpb25fZGVzY3JpcHRpb24pCnRlc3RfYzUwJGxvY2F0aW9uX2Rlc2NyaXB0aW9uIDwtIGFzLmZhY3Rvcih0ZXN0X2M1MCRsb2NhdGlvbl9kZXNjcmlwdGlvbikKI3RyYWluX2M1MCRhcnJlc3QgPC0gYXMubnVtZXJpYyh0cmFpbl9jNTAkYXJyZXN0LCB1bmlxdWUodHJhaW5fYzUwJGFycmVzdCkpCiN0ZXN0X2M1MCRhcnJlc3QgPC0gYXMubnVtZXJpYyh0ZXN0X2M1MCRhcnJlc3QsIHVuaXF1ZSh0ZXN0X2M1MCRhcnJlc3QpKQojdHJhaW5fYzUwJHByaW1hcnlfdHlwZSA8LSBhcy5udW1lcmljKHRyYWluX2M1MCRwcmltYXJ5X3R5cGUsIHVuaXF1ZSh0cmFpbl9jNTAkcHJpbWFyeV90eXBlKSkKI3Rlc3RfYzUwJHByaW1hcnlfdHlwZSA8LSBhcy5udW1lcmljKHRlc3RfYzUwJHByaW1hcnlfdHlwZSwgdW5pcXVlKHRlc3RfYzUwJHByaW1hcnlfdHlwZSkpCiN0cmFpbl9jNTAkbG9jYXRpb25fZGVzY3JpcHRpb24gPC0gYXMubnVtZXJpYyh0cmFpbl9jNTAkbG9jYXRpb25fZGVzY3JpcHRpb24sIHVuaXF1ZSh0cmFpbl9jNTAkbG9jYXRpb25fZGVzY3JpcHRpb24pKQojdGVzdF9jNTAkbG9jYXRpb25fZGVzY3JpcHRpb24gPC0gYXMubnVtZXJpYyh0ZXN0X2M1MCRsb2NhdGlvbl9kZXNjcmlwdGlvbiwgdW5pcXVlKHRlc3RfYzUwJGxvY2F0aW9uX2Rlc2NyaXB0aW9uKSkKI3RyYWluX2M1MCRkaXN0cmljdCA8LSBhcy5udW1lcmljKHRyYWluX2M1MCRkaXN0cmljdCwgdW5pcXVlKHRyYWluX2M1MCRkaXN0cmljdCkpCiN0ZXN0X2M1MCRkaXN0cmljdCA8LSBhcy5udW1lcmljKHRlc3RfYzUwJGRpc3RyaWN0LCB1bmlxdWUodGVzdF9jNTAkZGlzdHJpY3QpKQp0cmFpbl9jNTAkYXJyZXN0IDwtIGFzLmZhY3Rvcih0cmFpbl9jNTAkYXJyZXN0KQp0ZXN0X2M1MCRhcnJlc3QgPC0gYXMuZmFjdG9yKHRlc3RfYzUwJGFycmVzdCkKdHJhaW5fYzUwJGRpc3RyaWN0IDwtIGFzLmZhY3Rvcih0cmFpbl9jNTAkZGlzdHJpY3QpCnRlc3RfYzUwJGRpc3RyaWN0IDwtIGFzLmZhY3Rvcih0ZXN0X2M1MCRkaXN0cmljdCkKdHJhaW5fYzUwJGRpc3RyaWN0IDwtIGZhY3Rvcih0cmFpbl9jNTAkZGlzdHJpY3QpCnRlc3RfYzUwJGRpc3RyaWN0IDwtIGZhY3Rvcih0ZXN0X2M1MCRkaXN0cmljdCkKI3RyYWluX2M1MCRwcmltYXJ5X3R5cGUgPC0gYXMuZmFjdG9yKHRyYWluX2M1MCRwcmltYXJ5X3R5cGUpCiN0ZXN0X2M1MCRwcmltYXJ5X3R5cGUgPC0gYXMuZmFjdG9yKHRlc3RfYzUwJHByaW1hcnlfdHlwZSkKCgojQ3JlYXRpbmcgdGhlIGRlY2lzaW9uIHRyZWUgYWxnb3JpdGhtIEM0LjUgCnRyZWVfcmVzdWx0IDwtIEM1LjAoZGlzdHJpY3QgIH4gLiwgZGF0YT10cmFpbl9jNTAsIHRyaWFscyA9IDEwLGNvbnRyb2wgPSBDNS4wQ29udHJvbChub0dsb2JhbFBydW5pbmcgPSBGQUxTRSwgQ0Y9IDAuMDAwMDAxKSkgICNIaWdoZXIgQ0YgbGVzcyBwcnVubmluZwojc3VtbWFyeSh0cmVlX3Jlc3VsdCkKI1Bsb3R0aW5nIHRoZSB0cmVlCnBsb3QodHJlZV9yZXN1bHQsc3VidHJlZT1OVUxMLHRyaWFsPTkpCgojIyBQUkVESUNUSU9OCiNQcmVkaWN0aW9uIG9mIG5ldyBjYXNlcyBmcm9tIHRoZSB0ZXN0IGRhdGFzZXQKcHJlZGljdGlvbnMgPC0gcHJlZGljdCh0cmVlX3Jlc3VsdCwgbmV3ZGF0YSA9IHRlc3RfYzUwLCB0eXBlID0iY2xhc3MiKQoKI3RhYmxlKHByZWRpY3Rpb249cHJlZGljdGlvbnMsIHJlYWw9IGNyaW1lX3Rlc3RfYzUwJHByaW1hcnlfdHlwZSkKI2NyaW1lX3Rlc3RfYzUwJHByaW1hcnlfdHlwZSA8LSBmYWN0b3IoY3JpbWVfdGVzdF9jNTAkcHJpbWFyeV90eXBlKQplcnJvcl9jbGFzc2lmaWNhdGlvbiA8LSBtZWFuKHByZWRpY3Rpb25zICE9IHRlc3RfYzUwJGRpc3RyaWN0KQoKcGFzdGUoIlRoZSBjbGFzc2lmaWNhdGlvbiBlcnJvciBpbiB0ZXN0IHNldCBpczoiLCAxMDAqZXJyb3JfY2xhc3NpZmljYXRpb24sICIlIiwKICAgICAgc3VtKHByZWRpY3Rpb25zPT10ZXN0X2M1MCRkaXN0cmljdCksCiAgICAgICJjb3JyZWN0IGNsYXNzaWZpZWQgY2FzZXMgZnJvbSIsIGxlbmd0aChwcmVkaWN0aW9ucykpCgpwcmVkX3RyYWluIDwtIHByZWRpY3QodHJlZV9yZXN1bHQsIG5ld2RhdGEgPSB0cmFpbl9jNTApCiNjb25mdXNpb25NYXRyaXgocHJlZF90cmFpbiwgY3JpbWVfdHJhaW4kZGlzdHJpY3QpCiNwcmVkX3RyYWluPC1yb3VuZChwcmVkX3RyYWluKQojdGFibGUocHJlZGljdGlvbj1wcmVkX3RyYWluLCByZWFsPSBjcmltZV90cmFpbl9jNTAkYXJyZXN0KQoKZXJyb3JfY2xhc3NpZmljYXRpb24gPC0gbWVhbihwcmVkX3RyYWluICE9IHRyYWluX2M1MCRkaXN0cmljdCkKCnBhc3RlKCJUaGUgY2xhc3NpZmljYXRpb24gZXJyb3IgaW4gdHJhaW4gc2V0IGlzOiIsIDEwMCplcnJvcl9jbGFzc2lmaWNhdGlvbiwgIiUiLAogICAgICBzdW0ocHJlZF90cmFpbj09dHJhaW5fYzUwJGRpc3RyaWN0KSwKICAgICAgImNvcnJlY3QgY2xhc3NpZmllZCBjYXNlcyBmcm9tIiwgbGVuZ3RoKHByZWRfdHJhaW4pKQpgYGAKCmBgYHtyfQpzZXQuc2VlZCgxMjM0KQojd2VhcG9uc192aW9sYXRpb24gPC0gc3Vic2V0KHdlYXBvbnNfdmlvbGF0aW9uLCBzZWxlY3Q9LWMobG9jYXRpb25fZGVzY3JpcHRpb24pKQojd2VhcG9uc192aW9sYXRpb25fdHIgPC0gc3Vic2V0KHdlYXBvbnNfdmlvbGF0aW9uX3RyLCBzZWxlY3Q9LWMobG9jYXRpb25fZGVzY3JpcHRpb24pKQp3ZWFwb25zX3Zpb2xhdGlvbl90ciA8LSBzdWJzZXQod2VhcG9uc192aW9sYXRpb25fdHIsIGRpc3RyaWN0PT0iNiIgfCBkaXN0cmljdCA9PSAiMTEiIHwgZGlzdHJpY3QgPT0gIjciIHwgZGlzdHJpY3Q9PSI4IiB8IGRpc3RyaWN0ID09ICIxIiB8IGRpc3RyaWN0PT0iMTgiIHwgZGlzdHJpY3QgPT0gIjUiIHwgZGlzdHJpY3Q9PSI0IikKd2VhcG9uc192aW9sYXRpb24gPC0gc3Vic2V0KHdlYXBvbnNfdmlvbGF0aW9uLCBkaXN0cmljdD09IjYiIHwgZGlzdHJpY3QgPT0gIjExIiB8IGRpc3RyaWN0ID09ICI3IiB8IGRpc3RyaWN0PT0iOCIgfCBkaXN0cmljdCA9PSAiMSIgfCBkaXN0cmljdD09IjE4IiB8IGRpc3RyaWN0ID09ICI1IiB8IGRpc3RyaWN0PT0iNCIpCgp0cmFpbl9jNTA8LSBzdWJzZXQod2VhcG9uc192aW9sYXRpb25fdHIsIHNlbGVjdD0tYyhjYXNlX251bWJlcixibG9jayx3YXJkLGRlc2NyaXB0aW9uLGRheSxtb250aCxsYXRpdHVkZSxsb25naXR1ZGUpKQp0ZXN0X2M1MDwtIHN1YnNldCh3ZWFwb25zX3Zpb2xhdGlvbiwgc2VsZWN0PS1jKGNhc2VfbnVtYmVyLGJsb2NrLHdhcmQsZGVzY3JpcHRpb24sZGF5LG1vbnRoLGxhdGl0dWRlLGxvbmdpdHVkZSkpCgojY3JpbWVfc3BsaXRfYzUwPC0gaW5pdGlhbF9zcGxpdChzdWJzZXQoY2hpY2Fnb19jcmltZV9zdWJzZXRfdHIsIHNlbGVjdD0tYyhjYXNlX251bWJlcixibG9jayx3YXJkLGRlc2NyaXB0aW9uLGRheSxtb250aCxsYXRpdHVkZSxsb25naXR1ZGUpKSwgcHJvcD0wLjgpCiN0cmFpbl9jNTA8LSB0cmFpbmluZyhjcmltZV9zcGxpdF9jNTApCiN0ZXN0X2M1MDwtIHRlc3RpbmcoY3JpbWVfc3BsaXRfYzUwKQoKdHJhaW5fYzUwJGxvY2F0aW9uX2Rlc2NyaXB0aW9uIDwtIGFzLmZhY3Rvcih0cmFpbl9jNTAkbG9jYXRpb25fZGVzY3JpcHRpb24pCnRlc3RfYzUwJGxvY2F0aW9uX2Rlc2NyaXB0aW9uIDwtIGFzLmZhY3Rvcih0ZXN0X2M1MCRsb2NhdGlvbl9kZXNjcmlwdGlvbikKI3RyYWluX2M1MCRhcnJlc3QgPC0gYXMubnVtZXJpYyh0cmFpbl9jNTAkYXJyZXN0LCB1bmlxdWUodHJhaW5fYzUwJGFycmVzdCkpCiN0ZXN0X2M1MCRhcnJlc3QgPC0gYXMubnVtZXJpYyh0ZXN0X2M1MCRhcnJlc3QsIHVuaXF1ZSh0ZXN0X2M1MCRhcnJlc3QpKQojdHJhaW5fYzUwJHByaW1hcnlfdHlwZSA8LSBhcy5udW1lcmljKHRyYWluX2M1MCRwcmltYXJ5X3R5cGUsIHVuaXF1ZSh0cmFpbl9jNTAkcHJpbWFyeV90eXBlKSkKI3Rlc3RfYzUwJHByaW1hcnlfdHlwZSA8LSBhcy5udW1lcmljKHRlc3RfYzUwJHByaW1hcnlfdHlwZSwgdW5pcXVlKHRlc3RfYzUwJHByaW1hcnlfdHlwZSkpCnRyYWluX2M1MCRsb2NhdGlvbl9kZXNjcmlwdGlvbiA8LSBhcy5udW1lcmljKHRyYWluX2M1MCRsb2NhdGlvbl9kZXNjcmlwdGlvbiwgdW5pcXVlKHRyYWluX2M1MCRsb2NhdGlvbl9kZXNjcmlwdGlvbikpCnRlc3RfYzUwJGxvY2F0aW9uX2Rlc2NyaXB0aW9uIDwtIGFzLm51bWVyaWModGVzdF9jNTAkbG9jYXRpb25fZGVzY3JpcHRpb24sIHVuaXF1ZSh0ZXN0X2M1MCRsb2NhdGlvbl9kZXNjcmlwdGlvbikpCiN0cmFpbl9jNTAkZGlzdHJpY3QgPC0gYXMubnVtZXJpYyh0cmFpbl9jNTAkZGlzdHJpY3QsIHVuaXF1ZSh0cmFpbl9jNTAkZGlzdHJpY3QpKQojdGVzdF9jNTAkZGlzdHJpY3QgPC0gYXMubnVtZXJpYyh0ZXN0X2M1MCRkaXN0cmljdCwgdW5pcXVlKHRlc3RfYzUwJGRpc3RyaWN0KSkKI3RyYWluX2M1MCRhcnJlc3QgPC0gYXMuZmFjdG9yKHRyYWluX2M1MCRhcnJlc3QpCiN0ZXN0X2M1MCRhcnJlc3QgPC0gYXMuZmFjdG9yKHRlc3RfYzUwJGFycmVzdCkKdHJhaW5fYzUwJGRpc3RyaWN0IDwtIGFzLmZhY3Rvcih0cmFpbl9jNTAkZGlzdHJpY3QpCnRlc3RfYzUwJGRpc3RyaWN0IDwtIGFzLmZhY3Rvcih0ZXN0X2M1MCRkaXN0cmljdCkKdHJhaW5fYzUwJGRpc3RyaWN0IDwtIGZhY3Rvcih0cmFpbl9jNTAkZGlzdHJpY3QpCnRlc3RfYzUwJGRpc3RyaWN0IDwtIGZhY3Rvcih0ZXN0X2M1MCRkaXN0cmljdCkKI3RyYWluX2M1MCRwcmltYXJ5X3R5cGUgPC0gYXMuZmFjdG9yKHRyYWluX2M1MCRwcmltYXJ5X3R5cGUpCiN0ZXN0X2M1MCRwcmltYXJ5X3R5cGUgPC0gYXMuZmFjdG9yKHRlc3RfYzUwJHByaW1hcnlfdHlwZSkKCgojQ3JlYXRpbmcgdGhlIGRlY2lzaW9uIHRyZWUgYWxnb3JpdGhtIEM0LjUgCnRyZWVfcmVzdWx0IDwtIEM1LjAoZGlzdHJpY3QgIH4gLiwgZGF0YT10cmFpbl9jNTAsIGNvbnRyb2wgPSBDNS4wQ29udHJvbChub0dsb2JhbFBydW5pbmcgPSBGQUxTRSwgQ0Y9IDAuMDEpKSAgI0hpZ2hlciBDRiBsZXNzIHBydW5uaW5nCiNzdW1tYXJ5KHRyZWVfcmVzdWx0KQojUGxvdHRpbmcgdGhlIHRyZWUKcGxvdCh0cmVlX3Jlc3VsdCxzdWJ0cmVlPU5VTEwpCgojIyBQUkVESUNUSU9OCiNQcmVkaWN0aW9uIG9mIG5ldyBjYXNlcyBmcm9tIHRoZSB0ZXN0IGRhdGFzZXQKcHJlZGljdGlvbnMgPC0gcHJlZGljdCh0cmVlX3Jlc3VsdCwgbmV3ZGF0YSA9IHRlc3RfYzUwLCB0eXBlID0iY2xhc3MiKQoKI3RhYmxlKHByZWRpY3Rpb249cHJlZGljdGlvbnMsIHJlYWw9IGNyaW1lX3Rlc3RfYzUwJHByaW1hcnlfdHlwZSkKI2NyaW1lX3Rlc3RfYzUwJHByaW1hcnlfdHlwZSA8LSBmYWN0b3IoY3JpbWVfdGVzdF9jNTAkcHJpbWFyeV90eXBlKQplcnJvcl9jbGFzc2lmaWNhdGlvbiA8LSBtZWFuKHByZWRpY3Rpb25zICE9IHRlc3RfYzUwJGRpc3RyaWN0KQoKcGFzdGUoIlRoZSBjbGFzc2lmaWNhdGlvbiBlcnJvciBpbiB0ZXN0IHNldCBpczoiLCAxMDAqZXJyb3JfY2xhc3NpZmljYXRpb24sICIlIiwKICAgICAgc3VtKHByZWRpY3Rpb25zPT10ZXN0X2M1MCRkaXN0cmljdCksCiAgICAgICJjb3JyZWN0IGNsYXNzaWZpZWQgY2FzZXMgZnJvbSIsIGxlbmd0aChwcmVkaWN0aW9ucykpCgpwcmVkX3RyYWluIDwtIHByZWRpY3QodHJlZV9yZXN1bHQsIG5ld2RhdGEgPSB0cmFpbl9jNTApCiNjb25mdXNpb25NYXRyaXgocHJlZF90cmFpbiwgY3JpbWVfdHJhaW4kZGlzdHJpY3QpCiNwcmVkX3RyYWluPC1yb3VuZChwcmVkX3RyYWluKQojdGFibGUocHJlZGljdGlvbj1wcmVkX3RyYWluLCByZWFsPSBjcmltZV90cmFpbl9jNTAkYXJyZXN0KQoKZXJyb3JfY2xhc3NpZmljYXRpb24gPC0gbWVhbihwcmVkX3RyYWluICE9IHRyYWluX2M1MCRkaXN0cmljdCkKCnBhc3RlKCJUaGUgY2xhc3NpZmljYXRpb24gZXJyb3IgaW4gdHJhaW4gc2V0IGlzOiIsIDEwMCplcnJvcl9jbGFzc2lmaWNhdGlvbiwgIiUiLAogICAgICBzdW0ocHJlZF90cmFpbj09dHJhaW5fYzUwJGRpc3RyaWN0KSwKICAgICAgImNvcnJlY3QgY2xhc3NpZmllZCBjYXNlcyBmcm9tIiwgbGVuZ3RoKHByZWRfdHJhaW4pKQpgYGAKYGBge3J9CmxpYnJhcnkoTUFTUykgICAgICAgIyBmb3Igb2J0YWluaW5nIGRhdGEKbGlicmFyeSh0aWR5dmVyc2UpICAjIGZvciBkYXRhIHByb2Nlc3NpbmcKbGlicmFyeShycGFydCkgICAgICAjIGZvciBDQVJUIGRlY2lzaW9uIHRyZWUKbGlicmFyeShycGFydC5wbG90KSAjIGZvciBwbG90dGluZyBDQVJUCmxpYnJhcnkoY2FyZXQpICAgICAgIyBmb3IgY29uZnVzaW9uIG1hdHJpeCBhbmQgbW9yZQpsaWJyYXJ5KHJzYW1wbGUpICAgICMgZm9yIGRhdGEgc3BsaXR0aW5nCmxpYnJhcnkocmFuZG9tRm9yZXN0KSAgIyBGb3IgYmFnZ2luZyBhbmQgcmFuZG9tZm9yZXN0CmxpYnJhcnkoZ2dwdWJyKQoKIyMgU29sbyBzZSBwdWVkZW4gdGVuZXIgNTMgdmFsb3JlcyBjYXRlZ29yaWNvcyB1bmljb3MgZGlmZXJlbnRlcy4gUG9yIGVzdGEgcmF6b24gaGF5IHF1ZSBoYWNlciByZWdyZXNpb24gY29uIHNvbG8gZXN0YXMgdmFyaWFibGVzLgpjaGljYWdvX2NyaW1lX2Vuc2VtYmxlIDwtIHN1YnNldChjaGljYWdvX2NyaW1lX3N1YnNldCwgc2VsZWN0PS1jKGNhc2VfbnVtYmVyLGJsb2NrLGRlc2NyaXB0aW9uLGxvY2F0aW9uX2Rlc2NyaXB0aW9uLHdhcmQsbGF0aXR1ZGUsbG9uZ2l0dWRlKSkKY2hpY2Fnb19jcmltZV9lbnNlbWJsZV90ciA8LSBzdWJzZXQoY2hpY2Fnb19jcmltZV9zdWJzZXRfdHIsIHNlbGVjdD0tYyhjYXNlX251bWJlcixsb2NhdGlvbl9kZXNjcmlwdGlvbixkZXNjcmlwdGlvbixibG9jayx3YXJkLGxhdGl0dWRlLGxvbmdpdHVkZSkpCgpjaGljYWdvX2NyaW1lX2Vuc2VtYmxlJHByaW1hcnlfdHlwZSA8LSBhcy5udW1lcmljKGNoaWNhZ29fY3JpbWVfZW5zZW1ibGUkcHJpbWFyeV90eXBlKQpjaGljYWdvX2NyaW1lX2Vuc2VtYmxlJGFycmVzdCA8LSBhcy5mYWN0b3IoY2hpY2Fnb19jcmltZV9lbnNlbWJsZSRhcnJlc3QpCmNoaWNhZ29fY3JpbWVfZW5zZW1ibGUkYXJyZXN0IDwtIGFzLm51bWVyaWMoY2hpY2Fnb19jcmltZV9lbnNlbWJsZSRhcnJlc3QpCiNjaGljYWdvX2NyaW1lX2Vuc2VtYmxlJHByaW1hcnlfdHlwZSA8LSBhcy5mYWN0b3IoY2hpY2Fnb19jcmltZV9lbnNlbWJsZSRwcmltYXJ5X3R5cGUpCiNjaGljYWdvX2NyaW1lX2Vuc2VtYmxlJGRlc2NyaXB0aW9uIDwtIGFzLmZhY3RvcihjaGljYWdvX2NyaW1lX2Vuc2VtYmxlJGRlc2NyaXB0aW9uKQojY2hpY2Fnb19jcmltZV9lbnNlbWJsZSRkZXNjcmlwdGlvbiA8LSBmYWN0b3IoY2hpY2Fnb19jcmltZV9lbnNlbWJsZSRkZXNjcmlwdGlvbikKI2NoaWNhZ29fY3JpbWVfZW5zZW1ibGUkcHJpbWFyeV90eXBlIDwtIGZhY3RvcihjaGljYWdvX2NyaW1lX2Vuc2VtYmxlJHByaW1hcnlfdHlwZSkKCmNoaWNhZ29fY3JpbWVfZW5zZW1ibGVfdHIkcHJpbWFyeV90eXBlIDwtIGFzLm51bWVyaWMoY2hpY2Fnb19jcmltZV9lbnNlbWJsZV90ciRwcmltYXJ5X3R5cGUpCmNoaWNhZ29fY3JpbWVfZW5zZW1ibGVfdHIkYXJyZXN0IDwtIGFzLmZhY3RvcihjaGljYWdvX2NyaW1lX2Vuc2VtYmxlX3RyJGFycmVzdCkKY2hpY2Fnb19jcmltZV9lbnNlbWJsZV90ciRhcnJlc3QgPC0gYXMubnVtZXJpYyhjaGljYWdvX2NyaW1lX2Vuc2VtYmxlX3RyJGFycmVzdCkKI2NoaWNhZ29fY3JpbWVfZW5zZW1ibGVfdHIkcHJpbWFyeV90eXBlIDwtIGFzLmZhY3RvcihjaGljYWdvX2NyaW1lX2Vuc2VtYmxlX3RyJHByaW1hcnlfdHlwZSkKI2NoaWNhZ29fY3JpbWVfZW5zZW1ibGVfdHIkZGVzY3JpcHRpb24gPC0gYXMuZmFjdG9yKGNoaWNhZ29fY3JpbWVfZW5zZW1ibGVfdHIkZGVzY3JpcHRpb24pCiNjaGljYWdvX2NyaW1lX2Vuc2VtYmxlX3RyJGRlc2NyaXB0aW9uIDwtIGZhY3RvcihjaGljYWdvX2NyaW1lX2Vuc2VtYmxlX3RyJGRlc2NyaXB0aW9uKQojY2hpY2Fnb19jcmltZV9lbnNlbWJsZV90ciRwcmltYXJ5X3R5cGUgPC0gZmFjdG9yKGNoaWNhZ29fY3JpbWVfZW5zZW1ibGVfdHIkcHJpbWFyeV90eXBlKQoKY2hpY2Fnb19jcmltZV9lbnNlbWJsZV90ciA8LSBuYS5vbWl0KGNoaWNhZ29fY3JpbWVfZW5zZW1ibGVfdHIpCmNoaWNhZ29fY3JpbWVfZW5zZW1ibGUgPC0gbmEub21pdChjaGljYWdvX2NyaW1lX2Vuc2VtYmxlKQoKI1JGX3NwbGl0PC0gaW5pdGlhbF9zcGxpdChjaGljYWdvX2NyaW1lLCBwcm9wPTAuOCkKUkZfdHJhaW48LSBjaGljYWdvX2NyaW1lX2Vuc2VtYmxlX3RyWzE6MTAwMDAsXQpSRl90ZXN0PC0gY2hpY2Fnb19jcmltZV9lbnNlbWJsZVsxOjEwMDAsXQoKYmFnZ2luZ19tb2RlbDwtIHJhbmRvbUZvcmVzdChmb3JtdWxhPXByaW1hcnlfdHlwZSAgfiAuLCBkYXRhPVJGX3RyYWluLG10cnk9NCkgICM0IGZyb20gMTMgcHJlZGljdG9ycyB3aWxsIGJlIHNlbGVjdGVkCgojUmVzdWx0IG9mIHJhbmRvbSBmb3Jlc3QgbW9kZWwKcHJpbnQoYmFnZ2luZ19tb2RlbCkKCmBgYAojIyBSRURFUyBORVVST05BTEVTCmBgYHtyfQojIyBSRURFUwpjaGljYWdvX2NyaW1lX25uIDwtIHN1YnNldChjaGljYWdvX2NyaW1lX3N1YnNldCwgc2VsZWN0PS1jKGNhc2VfbnVtYmVyLGJsb2NrLHdhcmQsZGF5LGxhdGl0dWRlLGxvbmdpdHVkZSkpCmNoaWNhZ29fY3JpbWVfbm5fdHIgPC0gc3Vic2V0KGNoaWNhZ29fY3JpbWVfc3Vic2V0X3RyLCBzZWxlY3Q9LWMoY2FzZV9udW1iZXIsYmxvY2ssd2FyZCxkYXksbGF0aXR1ZGUsbG9uZ2l0dWRlKSkKCmxpYnJhcnkoa29ob25lbikgIyBmb3IgYnVpbGRpbmcgdGhlIFNPTSBtYXAKbGlicmFyeShjYXJldCkgICAgICNmb3IgY29uZnVzaW9uIG1hdHJpeAoKI0V4dHJhY3RpbmcgdGFyZ2V0IHZhcmlhYmxlCnRhcmdldF90cmFpbiA8LSBjaGljYWdvX2NyaW1lX25uX3RyJHByaW1hcnlfdHlwZQpjaGljYWdvX2NyaW1lX25uX3RyIDwtIHN1YnNldChjaGljYWdvX2NyaW1lX25uX3RyLCBzZWxlY3Q9LWMocHJpbWFyeV90eXBlKSkKCmNoaWNhZ29fY3JpbWVfbm5fdHIkYXJyZXN0IDwtIGFzLmZhY3RvcihjaGljYWdvX2NyaW1lX25uX3RyJGFycmVzdCkKY2hpY2Fnb19jcmltZV9ubl90ciRhcnJlc3QgPC0gYXMubnVtZXJpYyhjaGljYWdvX2NyaW1lX25uX3RyJGFycmVzdCkKI2NoaWNhZ29fY3JpbWUkcHJpbWFyeV90eXBlIDwtIGFzLm51bWVyaWMoY2hpY2Fnb19jcmltZSRwcmltYXJ5X3R5cGUpCmNoaWNhZ29fY3JpbWVfbm5fdHIkZGlzdHJpY3QgPC0gYXMubnVtZXJpYyhjaGljYWdvX2NyaW1lX25uX3RyJGRpc3RyaWN0KQojY2hpY2Fnb19jcmltZV9ubl90ciRkaXN0cmljdCA8LSBhcy5mYWN0b3IoY2hpY2Fnb19jcmltZV9ubl90ciRkaXN0cmljdCkKY2hpY2Fnb19jcmltZV9ubl90ciRkZXNjcmlwdGlvbiA8LSBhcy5mYWN0b3IoY2hpY2Fnb19jcmltZV9ubl90ciRkZXNjcmlwdGlvbikKY2hpY2Fnb19jcmltZV9ubl90ciRkZXNjcmlwdGlvbiA8LSBhcy5udW1lcmljKGNoaWNhZ29fY3JpbWVfbm5fdHIkZGVzY3JpcHRpb24pCmNoaWNhZ29fY3JpbWVfbm5fdHIkbG9jYXRpb25fZGVzY3JpcHRpb24gPC0gYXMuZmFjdG9yKGNoaWNhZ29fY3JpbWVfbm5fdHIkbG9jYXRpb25fZGVzY3JpcHRpb24pCmNoaWNhZ29fY3JpbWVfbm5fdHIkbG9jYXRpb25fZGVzY3JpcHRpb24gPC0gYXMubnVtZXJpYyhjaGljYWdvX2NyaW1lX25uX3RyJGxvY2F0aW9uX2Rlc2NyaXB0aW9uKQpjaGljYWdvX2NyaW1lX25uX3RyJG1vbnRoIDwtIGFzLm51bWVyaWMoY2hpY2Fnb19jcmltZV9ubl90ciRtb250aCkKI2NoaWNhZ29fY3JpbWVfbm5fdHIkbW9udGggPC0gYXMuZmFjdG9yKGNoaWNhZ29fY3JpbWVfbm5fdHIkbW9udGgpCgojU2NhbGluZyBvcmlnaW5hbCBkYXRhCnNldC5zZWVkKDcpCgoKIyBjcmVhdGlvbiBvZiB0cmFpbmluZyBhbmQgdGVzdCBkYXRhc2V0cwppbmRleCA8LSBzYW1wbGUobnJvdyhjaGljYWdvX2NyaW1lX25uX3RyKSwgcm91bmQoMC43NSpucm93KGNoaWNhZ29fY3JpbWVfbm5fdHIpKSkKdHJhaW4gPC0gY2hpY2Fnb19jcmltZV9ubl90cltpbmRleCxdCnRlc3QgPC0gY2hpY2Fnb19jcmltZV9ubl90clstaW5kZXgsXQoKdHJhaW4gPC0gYXMubWF0cml4KHRyYWluKQp0ZXN0IDwtIGFzLm1hdHJpeCh0ZXN0KQoKdHJhaW5fbGFiZWw8LXRhcmdldF90cmFpbltpbmRleF0KdGVzdF9sYWJlbDwtdGFyZ2V0X3RyYWluWy1pbmRleF0KCiNtYWluIGNoYXJhY3RlcmlzdGljcyBvZiB0aGUgbWFwCnNvbV9ncmlkPC1zb21ncmlkKHhkaW09OCwgeWRpbT04LCB0b3BvPSJoZXhhZ29uYWwiKQoKI3RyYWluaW5nIHRoZSBtYXAKY3JpbWUuc29tIDwtIHNvbSh0cmFpblsxOjEwMDAwMCxdLCBncmlkPXNvbV9ncmlkLCAKICAgICAgICAgICAgICAgcmxlbj0xMDAsIGFscGhhPWMoMC4wNSwgMC4wMSksIAogICAgICAgICAgICAgICByYWRpdXM9IDIsIGtlZXAuZGF0YT1UKQoKIyBOYW1lcyBvZiB0aGUgdmFyaWFibGVzIHVzZWQKY29sbmFtZXModHJhaW4pCgojIG1haW4gY2hhcmFjdGVyaXN0aWNzIG9mIHRoZSBtYXAKc3VtbWFyeShjcmltZS5zb20pCgojU2hvd2luZyB0aGUgdHJhaW5pbmcgcHJvY2VzcwpwbG90KGNyaW1lLnNvbSwgdHlwZT0iY2hhbmdlcyIpCgojbm9kZSBjb3VudHMKcGxvdChjcmltZS5zb20sIHR5cGU9ImNvdW50cyIsIG1haW49IkV4YW1wbGVzIHBlciBOZXVyb24iKQoKI0NvZGVzL1dlaWdodCB2ZWN0b3JzCnBsb3QoY3JpbWUuc29tLCB0eXBlPSJjb2RlcyIsIG1haW49IlBhdHRlcm5zIERpc2NvdmVyZWQiKQoKY29vbEJsdWVIT3RSZWQ8LWZ1bmN0aW9uKG4sIGFscGhhPTEpe3JhaW5ib3cobixlbmQ9NC82LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWxwaGE9YWxwaGEpW246MV19CnBhcihtZnJvdz1jKDIsMykpCnBsb3QoY3JpbWUuc29tLCB0eXBlPSJwcm9wZXJ0eSIsIHByb3BlcnR5PWdldENvZGVzKGNyaW1lLnNvbSwgMSlbLDFdLAogICAgIG1haW49Y29sbmFtZXMoZ2V0Q29kZXMoY3JpbWUuc29tLCAxKSlbMV0sCiAgICAgcGFsZXR0ZS5uYW1lPWNvb2xCbHVlSE90UmVkKQpwbG90KGNyaW1lLnNvbSwgdHlwZT0icHJvcGVydHkiLCBwcm9wZXJ0eT1nZXRDb2RlcyhjcmltZS5zb20sIDEpWywyXSwKICAgICBtYWluPWNvbG5hbWVzKGdldENvZGVzKGNyaW1lLnNvbSwgMSkpWzJdLAogICAgIHBhbGV0dGUubmFtZT1jb29sQmx1ZUhPdFJlZCkKcGxvdChjcmltZS5zb20sIHR5cGU9InByb3BlcnR5IiwgcHJvcGVydHk9Z2V0Q29kZXMoY3JpbWUuc29tLCAxKVssM10sCiAgICAgbWFpbj1jb2xuYW1lcyhnZXRDb2RlcyhjcmltZS5zb20sIDEpKVszXSwKICAgICBwYWxldHRlLm5hbWU9Y29vbEJsdWVIT3RSZWQpCnBsb3QoY3JpbWUuc29tLCB0eXBlPSJwcm9wZXJ0eSIsIHByb3BlcnR5PWdldENvZGVzKGNyaW1lLnNvbSwgMSlbLDRdLAogICAgIG1haW49Y29sbmFtZXMoZ2V0Q29kZXMoY3JpbWUuc29tLCAxKSlbNF0sCiAgICAgcGFsZXR0ZS5uYW1lPWNvb2xCbHVlSE90UmVkKQpwbG90KGNyaW1lLnNvbSwgdHlwZT0icHJvcGVydHkiLCBwcm9wZXJ0eT1nZXRDb2RlcyhjcmltZS5zb20sIDEpWyw1XSwKICAgICBtYWluPWNvbG5hbWVzKGdldENvZGVzKGNyaW1lLnNvbSwgMSkpWzVdLAogICAgIHBhbGV0dGUubmFtZT1jb29sQmx1ZUhPdFJlZCkKI3Bsb3QoY3JpbWUuc29tLCB0eXBlPSJwcm9wZXJ0eSIsIHByb3BlcnR5PWdldENvZGVzKGNyaW1lLnNvbSwgMSlbLDZdLAojICAgICBtYWluPWNvbG5hbWVzKGdldENvZGVzKGNyaW1lLnNvbSwgMSkpWzZdLAojICAgICBwYWxldHRlLm5hbWU9Y29vbEJsdWVIT3RSZWQpCgojIEFsdGVybmF0aXZlIGVhc2llcgpjb29sQmx1ZUhvdFJlZDwtZnVuY3Rpb24obiwgYWxwaGE9MSl7cmFpbmJvdyhuLGVuZD00LzYsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbHBoYT1hbHBoYSlbbjoxXX0KCnBhcihtZnJvdz1jKDUsMykpCmZvciAoaiBpbiAxOm5jb2wodHJhaW4pKSB7CnBsb3QoY3JpbWUuc29tLCB0eXBlPSJwcm9wZXJ0eSIsIHByb3BlcnR5PWNyaW1lLnNvbSRjb2Rlc1tbMV1dWyxqXSwKICAgICBwYWxldHRlLm5hbWU9Y29vbEJsdWVIb3RSZWQsCiAgICAgbWFpbj1jb2xuYW1lcyh0cmFpbilbal0sIGNleD0wLjUpCn0KCiNzb20ucHJlZGljdGlvbiA8LSBwcmVkaWN0KGNyaW1lLnNvbSwgdGVzdCkKYGBgCmBgYHtyfQojQ2x1c3RlcmluZyBwYXR0ZXJucyBpbiB0aGUgbWFwCmdyb3VwczwtOAojQXBwbHlpbmcgaGllcmFyY2hpY2FsIGNsdXN0ZXJpbmcgZm9yIGdyb3VwaW5nIHBhdHRlcm5zCmNyaW1lLmhjPWN1dHJlZShoY2x1c3QoZGlzdChjcmltZS5zb20kY29kZXNbWzFdXSkpLCBncm91cHMpCnBsb3QoY3JpbWUuc29tLCB0eXBlPSJjb2RlcyIsIGJnY29sID0gcmFpbmJvdyhncm91cHMpW2NyaW1lLmhjXSwKICAgICBtYWluPSJjbHVzdGVyaW5nIHRoZSBwYXR0ZXJucyBkaXNjb3ZlcmVkIikKYWRkLmNsdXN0ZXIuYm91bmRhcmllcyhjcmltZS5zb20sY3JpbWUuaGMpCmBgYApgYGB7cn0KCiNTY2FsaW5nIG9yaWdpbmFsIGRhdGEKc2V0LnNlZWQoNykKCiNtYWluIGNoYXJhY3RlcmlzdGljcyBvZiB0aGUgbWFwCnNvbV9ncmlkPC1zb21ncmlkKHhkaW09OCwgeWRpbT04LCB0b3BvPSJoZXhhZ29uYWwiKQpzZXQuc2VlZCg3KQprb2htYXAgPC0geHlmKHRyYWluWzE6MTAwMDAwLF0sIHRyYWluX2xhYmVsWzE6MTAwMDAwXSwKICAgICAgICAgICAgICBncmlkPXNvbV9ncmlkLCAKICAgICAgICAgICAgICBybGVuPTEwMCwgYWxwaGE9YygwLjA1LCAwLjAxKSwgCiAgICAgICAgICAgICAgcmFkaXVzPSAyLCBrZWVwLmRhdGE9VCkKCiNTaG93aW5nIHRoZSB0cmFpbmluZyBwcm9jZXNzCnBsb3Qoa29obWFwLCB0eXBlPSJjaGFuZ2VzIikKCiNTaG93aW5nIGRpc3RyaWJ1dGlvbiBvZiB3aW5lIGxhYmVscyBpbiBuZXVyb25zCnBsb3Qoa29obWFwLCB0eXBlPSJjb2RlcyIsICBjb2RlUmVuZGVyaW5nID0gImxpbmVzIiwgc2hhcGU9InN0cmFpZ2h0IiwKICAgICBtYWluPWMoIkNyaW1lIikpCgpwbG90KGtvaG1hcCwgdHlwZT0iY29kZXMiLCAgY29kZVJlbmRlcmluZyA9ICJsaW5lcyIsIHNoYXBlPSJzdHJhaWdodCIsCiAgICAgbWFpbj1jKCIgcGF0dGVybnMiKSkKCiMgUGxvdHRpbmcgY2xhc3NlcyBpbiBuZXVyb25zCnBsb3Qoa29obWFwLCB0eXBlPSJtYXBwaW5nIiwgbGFiZWxzPWFzLm51bWVyaWModHJhaW5fbGFiZWwpKzMsCiAgICAgY29sPWFzLm51bWVyaWModHJhaW5fbGFiZWwpKzMsIHBjaD00LCBtYWluPSJNYXAgb2YgY2xhc3NlcyIsIHBhbGV0dGUubmFtZSA9IHRlcnJhaW4uY29sb3JzKQoKI1ByZWRpY3Rpb24gdXNpbmcgdGhlIHRyYWluaW5nIGRhdGEKcHJpbnQoIlRSQUlOSU5HIFBSRURJQ1RJT04iKQprb2htYXAucHJlZGljdF90cjwtIHByZWRpY3Qoa29obWFwLCBuZXdkYXRhPXRyYWluLCB3aGF0bWFwID0gMSkKcHJlZGljdGlvbl90YWJsZV90cjwtdGFibGUodHJhaW5fbGFiZWwsa29obWFwLnByZWRpY3RfdHIkcHJlZGljdGlvbnNbWzJdXSkKY29uZnVzaW9uTWF0cml4KHByZWRpY3Rpb25fdGFibGVfdHIpCgojUHJlZGljdGlvbiB1c2luZyB0aGUgdGVzdCBkYXRhCnByaW50KCJURVNUIFBSRURJQ1RJT04iKQprb2htYXAucHJlZGljdDwtIHByZWRpY3Qoa29obWFwLCBuZXdkYXRhPXRlc3QsIHdoYXRtYXAgPSAxKQpwcmVkaWN0aW9uX3RhYmxlPC10YWJsZSh0ZXN0X2xhYmVsLGtvaG1hcC5wcmVkaWN0JHByZWRpY3Rpb25zW1syXV0pCmNvbmZ1c2lvbk1hdHJpeChwcmVkaWN0aW9uX3RhYmxlKQpgYGAKYGBge3J9CiMjIFJFREVTCmNoaWNhZ29fY3JpbWVfbm4yIDwtIHN1YnNldChjaGljYWdvX2NyaW1lX3N1YnNldCwgc2VsZWN0PS1jKGRlc2NyaXB0aW9uLGNhc2VfbnVtYmVyLGJsb2NrLGRheSxsYXRpdHVkZSxsb25naXR1ZGUpKQpjaGljYWdvX2NyaW1lX25uX3RyMiA8LSBzdWJzZXQoY2hpY2Fnb19jcmltZV9zdWJzZXRfdHIsIHNlbGVjdD0tYyhkZXNjcmlwdGlvbixjYXNlX251bWJlcixibG9jayxkYXksbGF0aXR1ZGUsbG9uZ2l0dWRlKSkKCmxpYnJhcnkoa29ob25lbikgIyBmb3IgYnVpbGRpbmcgdGhlIFNPTSBtYXAKbGlicmFyeShjYXJldCkgICAgICNmb3IgY29uZnVzaW9uIG1hdHJpeAoKI0V4dHJhY3RpbmcgdGFyZ2V0IHZhcmlhYmxlCnRhcmdldF90cmFpbjIgPC0gY2hpY2Fnb19jcmltZV9ubl90cjIkcHJpbWFyeV90eXBlCmNoaWNhZ29fY3JpbWVfbm5fdHIyIDwtIHN1YnNldChjaGljYWdvX2NyaW1lX25uX3RyMiwgc2VsZWN0PS1jKHByaW1hcnlfdHlwZSkpCgp0YXJnZXRfdGVzdDIgPC0gY2hpY2Fnb19jcmltZV9ubjIkcHJpbWFyeV90eXBlCmNoaWNhZ29fY3JpbWVfbm4yIDwtIHN1YnNldChjaGljYWdvX2NyaW1lX25uMiwgc2VsZWN0PS1jKHByaW1hcnlfdHlwZSkpCgpjaGljYWdvX2NyaW1lX25uX3RyMiRhcnJlc3QgPC0gYXMuZmFjdG9yKGNoaWNhZ29fY3JpbWVfbm5fdHIyJGFycmVzdCkKY2hpY2Fnb19jcmltZV9ubl90cjIkYXJyZXN0IDwtIGFzLm51bWVyaWMoY2hpY2Fnb19jcmltZV9ubl90cjIkYXJyZXN0KQojY2hpY2Fnb19jcmltZSRwcmltYXJ5X3R5cGUgPC0gYXMubnVtZXJpYyhjaGljYWdvX2NyaW1lJHByaW1hcnlfdHlwZSkKY2hpY2Fnb19jcmltZV9ubl90cjIkZGlzdHJpY3QgPC0gYXMubnVtZXJpYyhjaGljYWdvX2NyaW1lX25uX3RyMiRkaXN0cmljdCkKI2NoaWNhZ29fY3JpbWVfbm5fdHIkZGlzdHJpY3QgPC0gYXMuZmFjdG9yKGNoaWNhZ29fY3JpbWVfbm5fdHIkZGlzdHJpY3QpCiNjaGljYWdvX2NyaW1lX25uX3RyMiRkZXNjcmlwdGlvbiA8LSBhcy5mYWN0b3IoY2hpY2Fnb19jcmltZV9ubl90cjIkZGVzY3JpcHRpb24pCiNjaGljYWdvX2NyaW1lX25uX3RyMiRkZXNjcmlwdGlvbiA8LSBhcy5udW1lcmljKGNoaWNhZ29fY3JpbWVfbm5fdHIyJGRlc2NyaXB0aW9uKQpjaGljYWdvX2NyaW1lX25uX3RyMiRsb2NhdGlvbl9kZXNjcmlwdGlvbiA8LSBhcy5mYWN0b3IoY2hpY2Fnb19jcmltZV9ubl90cjIkbG9jYXRpb25fZGVzY3JpcHRpb24pCmNoaWNhZ29fY3JpbWVfbm5fdHIyJGxvY2F0aW9uX2Rlc2NyaXB0aW9uIDwtIGFzLm51bWVyaWMoY2hpY2Fnb19jcmltZV9ubl90cjIkbG9jYXRpb25fZGVzY3JpcHRpb24pCmNoaWNhZ29fY3JpbWVfbm5fdHIyJG1vbnRoIDwtIGFzLm51bWVyaWMoY2hpY2Fnb19jcmltZV9ubl90cjIkbW9udGgpCmNoaWNhZ29fY3JpbWVfbm5fdHIkbW9udGggPC0gYXMuZmFjdG9yKGNoaWNhZ29fY3JpbWVfbm5fdHIkbW9udGgpCgojU2NhbGluZyBvcmlnaW5hbCBkYXRhCnNldC5zZWVkKDcpCgojIGNyZWF0aW9uIG9mIHRyYWluaW5nIGFuZCB0ZXN0IGRhdGFzZXRzCmluZGV4IDwtIHNhbXBsZShucm93KGNoaWNhZ29fY3JpbWVfbm5fdHIyKSwgcm91bmQoMC43NSpucm93KGNoaWNhZ29fY3JpbWVfbm5fdHIyKSkpCnRyYWluIDwtIGNoaWNhZ29fY3JpbWVfbm5fdHIyW2luZGV4LF0KdGVzdCA8LSBjaGljYWdvX2NyaW1lX25uX3RyMlstaW5kZXgsXQoKdHJhaW4gPC0gYXMubWF0cml4KHRyYWluKQp0ZXN0IDwtIGFzLm1hdHJpeCh0ZXN0KQoKdHJhaW5fbGFiZWw8LXRhcmdldF90cmFpbjJbaW5kZXhdCnRlc3RfbGFiZWw8LXRhcmdldF90cmFpbjJbLWluZGV4XQoKI21haW4gY2hhcmFjdGVyaXN0aWNzIG9mIHRoZSBtYXAKc29tX2dyaWQ8LXNvbWdyaWQoeGRpbT04LCB5ZGltPTgsIHRvcG89ImhleGFnb25hbCIpCgojdHJhaW5pbmcgdGhlIG1hcApjcmltZS5zb20gPC0gc29tKHRyYWluWzE6MTAwMDAwLF0sIGdyaWQ9c29tX2dyaWQsIAogICAgICAgICAgICAgICBybGVuPTEwMCwgYWxwaGE9YygwLjA1LCAwLjAxKSwgCiAgICAgICAgICAgICAgIHJhZGl1cz0gMiwga2VlcC5kYXRhPVQpCgojIE5hbWVzIG9mIHRoZSB2YXJpYWJsZXMgdXNlZApjb2xuYW1lcyh0cmFpbikKCiMgbWFpbiBjaGFyYWN0ZXJpc3RpY3Mgb2YgdGhlIG1hcApzdW1tYXJ5KGNyaW1lLnNvbSkKCiNTaG93aW5nIHRoZSB0cmFpbmluZyBwcm9jZXNzCnBsb3QoY3JpbWUuc29tLCB0eXBlPSJjaGFuZ2VzIikKCiNub2RlIGNvdW50cwpwbG90KGNyaW1lLnNvbSwgdHlwZT0iY291bnRzIiwgbWFpbj0iRXhhbXBsZXMgcGVyIE5ldXJvbiIpCgojQ29kZXMvV2VpZ2h0IHZlY3RvcnMKcGxvdChjcmltZS5zb20sIHR5cGU9ImNvZGVzIiwgbWFpbj0iUGF0dGVybnMgRGlzY292ZXJlZCIpCgpjb29sQmx1ZUhPdFJlZDwtZnVuY3Rpb24obiwgYWxwaGE9MSl7cmFpbmJvdyhuLGVuZD00LzYsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbHBoYT1hbHBoYSlbbjoxXX0KcGFyKG1mcm93PWMoMiwzKSkKcGxvdChjcmltZS5zb20sIHR5cGU9InByb3BlcnR5IiwgcHJvcGVydHk9Z2V0Q29kZXMoY3JpbWUuc29tLCAxKVssMV0sCiAgICAgbWFpbj1jb2xuYW1lcyhnZXRDb2RlcyhjcmltZS5zb20sIDEpKVsxXSwKICAgICBwYWxldHRlLm5hbWU9Y29vbEJsdWVIT3RSZWQpCnBsb3QoY3JpbWUuc29tLCB0eXBlPSJwcm9wZXJ0eSIsIHByb3BlcnR5PWdldENvZGVzKGNyaW1lLnNvbSwgMSlbLDJdLAogICAgIG1haW49Y29sbmFtZXMoZ2V0Q29kZXMoY3JpbWUuc29tLCAxKSlbMl0sCiAgICAgcGFsZXR0ZS5uYW1lPWNvb2xCbHVlSE90UmVkKQpwbG90KGNyaW1lLnNvbSwgdHlwZT0icHJvcGVydHkiLCBwcm9wZXJ0eT1nZXRDb2RlcyhjcmltZS5zb20sIDEpWywzXSwKICAgICBtYWluPWNvbG5hbWVzKGdldENvZGVzKGNyaW1lLnNvbSwgMSkpWzNdLAogICAgIHBhbGV0dGUubmFtZT1jb29sQmx1ZUhPdFJlZCkKCgojIEFsdGVybmF0aXZlIGVhc2llcgpjb29sQmx1ZUhvdFJlZDwtZnVuY3Rpb24obiwgYWxwaGE9MSl7cmFpbmJvdyhuLGVuZD00LzYsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbHBoYT1hbHBoYSlbbjoxXX0KCmBgYApgYGB7cn0KI0NsdXN0ZXJpbmcgcGF0dGVybnMgaW4gdGhlIG1hcApsaWJyYXJ5KFJDb2xvckJyZXdlcikKZ3JvdXBzPC04CiNBcHBseWluZyBoaWVyYXJjaGljYWwgY2x1c3RlcmluZyBmb3IgZ3JvdXBpbmcgcGF0dGVybnMKY3JpbWUuaGM9Y3V0cmVlKGhjbHVzdChkaXN0KGNyaW1lLnNvbSRjb2Rlc1tbMV1dKSksIGdyb3VwcykKcGxvdChjcmltZS5zb20sIHR5cGU9ImNvZGVzIiwgYmdjb2wgPSBicmV3ZXIucGFsKGdyb3VwcywgbmFtZT0iWWxHbkJ1IilbY3JpbWUuaGNdLAogICAgIG1haW49ImNsdXN0ZXJpbmcgdGhlIHBhdHRlcm5zIGRpc2NvdmVyZWQiKQphZGQuY2x1c3Rlci5ib3VuZGFyaWVzKGNyaW1lLnNvbSxjcmltZS5oYykKYGBgCmBgYHtyfQojU2NhbGluZyBvcmlnaW5hbCBkYXRhCnNldC5zZWVkKDcpCgojbWFpbiBjaGFyYWN0ZXJpc3RpY3Mgb2YgdGhlIG1hcApzb21fZ3JpZDwtc29tZ3JpZCh4ZGltPTgsIHlkaW09OCwgdG9wbz0iaGV4YWdvbmFsIikKc2V0LnNlZWQoNykKa29obWFwIDwtIHh5Zih0cmFpblsxOjEwMDAwMCxdLCB0cmFpbl9sYWJlbFsxOjEwMDAwMF0sCiAgICAgICAgICAgICAgZ3JpZD1zb21fZ3JpZCwgCiAgICAgICAgICAgICAgcmxlbj0xMDAsIGFscGhhPWMoMC4wNSwgMC4wMSksIAogICAgICAgICAgICAgIHJhZGl1cz0gMiwga2VlcC5kYXRhPVQpCgojU2hvd2luZyB0aGUgdHJhaW5pbmcgcHJvY2VzcwpwbG90KGtvaG1hcCwgdHlwZT0iY2hhbmdlcyIpCgojU2hvd2luZyBkaXN0cmlidXRpb24gb2Ygd2luZSBsYWJlbHMgaW4gbmV1cm9ucwpwbG90KGtvaG1hcCwgdHlwZT0iY29kZXMiLCAgY29kZVJlbmRlcmluZyA9ICJsaW5lcyIsIHNoYXBlPSJzdHJhaWdodCIsCiAgICAgbWFpbj1jKCJDcmltZSIpKQoKcGxvdChrb2htYXAsIHR5cGU9ImNvZGVzIiwgIGNvZGVSZW5kZXJpbmcgPSAibGluZXMiLCBzaGFwZT0ic3RyYWlnaHQiLAogICAgIG1haW49YygiIHBhdHRlcm5zIikpCgojIFBsb3R0aW5nIGNsYXNzZXMgaW4gbmV1cm9ucwojcGxvdChrb2htYXAsIHR5cGU9Im1hcHBpbmciLCBsYWJlbHM9YXMubnVtZXJpYyh0cmFpbl9sYWJlbCkrMywKIyAgICAgY29sPWFzLm51bWVyaWModHJhaW5fbGFiZWwpKzMsIHBjaD00LCBtYWluPSJNYXAgb2YgY2xhc3NlcyIsIHBhbGV0dGUubmFtZSA9IHRlcnJhaW4uY29sb3JzKQoKI1ByZWRpY3Rpb24gdXNpbmcgdGhlIHRyYWluaW5nIGRhdGEKcHJpbnQoIlRSQUlOSU5HIFBSRURJQ1RJT04iKQprb2htYXAucHJlZGljdF90cjwtIHByZWRpY3Qoa29obWFwLCBuZXdkYXRhPXRyYWluLCB3aGF0bWFwID0gMSkKcHJlZGljdGlvbl90YWJsZV90cjwtdGFibGUodHJhaW5fbGFiZWwsa29obWFwLnByZWRpY3RfdHIkcHJlZGljdGlvbnNbWzJdXSkKY29uZnVzaW9uTWF0cml4KHByZWRpY3Rpb25fdGFibGVfdHIpCgojUHJlZGljdGlvbiB1c2luZyB0aGUgdGVzdCBkYXRhCnByaW50KCJURVNUIFBSRURJQ1RJT04iKQprb2htYXAucHJlZGljdDwtIHByZWRpY3Qoa29obWFwLCBuZXdkYXRhPXRlc3QsIHdoYXRtYXAgPSAxKQpwcmVkaWN0aW9uX3RhYmxlPC10YWJsZSh0ZXN0X2xhYmVsLGtvaG1hcC5wcmVkaWN0JHByZWRpY3Rpb25zW1syXV0pCmNvbmZ1c2lvbk1hdHJpeChwcmVkaWN0aW9uX3RhYmxlKQpgYGAKYGBge3J9CiMjIFJFREVTCm5hcmNvdGljc19ubiA8LSBzdWJzZXQobmFyY290aWNzX3RyLCBzZWxlY3Q9LWMoY2FzZV9udW1iZXIsYmxvY2ssZGF5LGxhdGl0dWRlLGxvbmdpdHVkZSkpCgpsaWJyYXJ5KGtvaG9uZW4pICMgZm9yIGJ1aWxkaW5nIHRoZSBTT00gbWFwCmxpYnJhcnkoY2FyZXQpICAgICAjZm9yIGNvbmZ1c2lvbiBtYXRyaXgKCiNFeHRyYWN0aW5nIHRhcmdldCB2YXJpYWJsZQp0YXJnZXRfdHJhaW4gPC0gbmFyY290aWNzX25uJGRpc3RyaWN0Cm5hcmNvdGljc19ubiA8LSBzdWJzZXQobmFyY290aWNzX25uLCBzZWxlY3Q9LWMoZGlzdHJpY3QpKQoKbmFyY290aWNzX25uJGFycmVzdCA8LSBhcy5mYWN0b3IobmFyY290aWNzX25uJGFycmVzdCkKbmFyY290aWNzX25uJGFycmVzdCA8LSBhcy5udW1lcmljKG5hcmNvdGljc19ubiRhcnJlc3QpCm5hcmNvdGljc19ubiRwcmltYXJ5X3R5cGUgPC0gYXMuZmFjdG9yKG5hcmNvdGljc19ubiRwcmltYXJ5X3R5cGUpCm5hcmNvdGljc19ubiRwcmltYXJ5X3R5cGUgPC0gYXMubnVtZXJpYyhuYXJjb3RpY3Nfbm4kcHJpbWFyeV90eXBlKQojbmFyY290aWNzX25uJGRpc3RyaWN0IDwtIGFzLm51bWVyaWMobmFyY290aWNzX25uJGRpc3RyaWN0KQojY2hpY2Fnb19jcmltZV9ubiRkaXN0cmljdCA8LSBhcy5mYWN0b3IoY2hpY2Fnb19jcmltZV9ubiRkaXN0cmljdCkKbmFyY290aWNzX25uJGRlc2NyaXB0aW9uIDwtIGFzLmZhY3RvcihuYXJjb3RpY3Nfbm4kZGVzY3JpcHRpb24pCm5hcmNvdGljc19ubiRkZXNjcmlwdGlvbiA8LSBhcy5udW1lcmljKG5hcmNvdGljc19ubiRkZXNjcmlwdGlvbikKbmFyY290aWNzX25uJGxvY2F0aW9uX2Rlc2NyaXB0aW9uIDwtIGFzLmZhY3RvcihuYXJjb3RpY3Nfbm4kbG9jYXRpb25fZGVzY3JpcHRpb24pCm5hcmNvdGljc19ubiRsb2NhdGlvbl9kZXNjcmlwdGlvbiA8LSBhcy5udW1lcmljKG5hcmNvdGljc19ubiRsb2NhdGlvbl9kZXNjcmlwdGlvbikKbmFyY290aWNzX25uJG1vbnRoIDwtIGFzLm51bWVyaWMobmFyY290aWNzX25uJG1vbnRoKQoKI1NjYWxpbmcgb3JpZ2luYWwgZGF0YQpzZXQuc2VlZCg3KQojdGFyZ2V0X3RyYWluLnNjPC1zY2FsZShjaGljYWdvX2NyaW1lX25uX3RyKQojdGFyZ2V0X3Rlc3Quc2M8LXNjYWxlKGNoaWNhZ29fY3JpbWVfbm4pCgojIGNyZWF0aW9uIG9mIHRyYWluaW5nIGFuZCB0ZXN0IGRhdGFzZXRzCmluZGV4IDwtIHNhbXBsZShucm93KG5hcmNvdGljc19ubiksIHJvdW5kKDAuNzUqbnJvdyhuYXJjb3RpY3Nfbm4pKSkKdHJhaW4gPC0gbmFyY290aWNzX25uW2luZGV4LF0KdGVzdCA8LSBuYXJjb3RpY3Nfbm5bLWluZGV4LF0KCiN0cmFpbiA8LSBjaGljYWdvX2NyaW1lX25uX3RyCnRyYWluIDwtIGFzLm1hdHJpeCh0cmFpbikKI3Rlc3QgPC0gY2hpY2Fnb19jcmltZV9ubgp0ZXN0IDwtIGFzLm1hdHJpeCh0ZXN0KQoKI3RyYWluX2xhYmVsPC10YXJnZXRfdHJhaW4KI3Rlc3RfbGFiZWw8LXRhcmdldF90ZXN0CnRyYWluX2xhYmVsPC10YXJnZXRfdHJhaW5baW5kZXhdCnRlc3RfbGFiZWw8LXRhcmdldF90cmFpblstaW5kZXhdCgojbWFpbiBjaGFyYWN0ZXJpc3RpY3Mgb2YgdGhlIG1hcApzb21fZ3JpZDwtc29tZ3JpZCh4ZGltPTgsIHlkaW09OCwgdG9wbz0iaGV4YWdvbmFsIikKCiN0cmFpbmluZyB0aGUgbWFwCmNyaW1lLnNvbSA8LSBzb20odHJhaW4sIGdyaWQ9c29tX2dyaWQsIAogICAgICAgICAgICAgICBybGVuPTEwMCwgYWxwaGE9YygwLjA1LCAwLjAxKSwgCiAgICAgICAgICAgICAgIHJhZGl1cz0gMiwga2VlcC5kYXRhPVQpCgojIE5hbWVzIG9mIHRoZSB2YXJpYWJsZXMgdXNlZApjb2xuYW1lcyh0cmFpbikKCiMgbWFpbiBjaGFyYWN0ZXJpc3RpY3Mgb2YgdGhlIG1hcApzdW1tYXJ5KGNyaW1lLnNvbSkKCiNTaG93aW5nIHRoZSB0cmFpbmluZyBwcm9jZXNzCnBsb3QoY3JpbWUuc29tLCB0eXBlPSJjaGFuZ2VzIikKCiNub2RlIGNvdW50cwpwbG90KGNyaW1lLnNvbSwgdHlwZT0iY291bnRzIiwgbWFpbj0iRXhhbXBsZXMgcGVyIE5ldXJvbiIpCgojQ29kZXMvV2VpZ2h0IHZlY3RvcnMKcGxvdChjcmltZS5zb20sIHR5cGU9ImNvZGVzIiwgbWFpbj0iUGF0dGVybnMgRGlzY292ZXJlZCIpCgpgYGAKYGBge3J9CiNTY2FsaW5nIG9yaWdpbmFsIGRhdGEKc2V0LnNlZWQoNykKCiNtYWluIGNoYXJhY3RlcmlzdGljcyBvZiB0aGUgbWFwCnNvbV9ncmlkPC1zb21ncmlkKHhkaW09OCwgeWRpbT04LCB0b3BvPSJoZXhhZ29uYWwiKQpzZXQuc2VlZCg3KQprb2htYXAgPC0geHlmKHRyYWluLCB0cmFpbl9sYWJlbCwKICAgICAgICAgICAgICBncmlkPXNvbV9ncmlkLCAKICAgICAgICAgICAgICBybGVuPTEwMCwgYWxwaGE9YygwLjA1LCAwLjAxKSwgCiAgICAgICAgICAgICAgcmFkaXVzPSAyLCBrZWVwLmRhdGE9VCkKCiNTaG93aW5nIHRoZSB0cmFpbmluZyBwcm9jZXNzCnBsb3Qoa29obWFwLCB0eXBlPSJjaGFuZ2VzIikKCiNTaG93aW5nIGRpc3RyaWJ1dGlvbiBvZiB3aW5lIGxhYmVscyBpbiBuZXVyb25zCnBsb3Qoa29obWFwLCB0eXBlPSJjb2RlcyIsICBjb2RlUmVuZGVyaW5nID0gImxpbmVzIiwgc2hhcGU9InN0cmFpZ2h0IiwKICAgICBtYWluPWMoIkNyaW1lIikpCgpwbG90KGtvaG1hcCwgdHlwZT0iY29kZXMiLCAgY29kZVJlbmRlcmluZyA9ICJsaW5lcyIsIHNoYXBlPSJzdHJhaWdodCIsCiAgICAgbWFpbj1jKCIgcGF0dGVybnMiKSkKCiNQcmVkaWN0aW9uIHVzaW5nIHRoZSB0cmFpbmluZyBkYXRhCnByaW50KCJUUkFJTklORyBQUkVESUNUSU9OIikKa29obWFwLnByZWRpY3RfdHI8LSBwcmVkaWN0KGtvaG1hcCwgbmV3ZGF0YT10cmFpbiwgd2hhdG1hcCA9IDEpCnByZWRpY3Rpb25fdGFibGVfdHI8LXRhYmxlKHRyYWluX2xhYmVsLGtvaG1hcC5wcmVkaWN0X3RyJHByZWRpY3Rpb25zW1syXV0pCmNvbmZ1c2lvbk1hdHJpeChwcmVkaWN0aW9uX3RhYmxlX3RyKQoKI1ByZWRpY3Rpb24gdXNpbmcgdGhlIHRlc3QgZGF0YQpwcmludCgiVEVTVCBQUkVESUNUSU9OIikKa29obWFwLnByZWRpY3Q8LSBwcmVkaWN0KGtvaG1hcCwgbmV3ZGF0YT10ZXN0LCB3aGF0bWFwID0gMSkKcHJlZGljdGlvbl90YWJsZTwtdGFibGUodGVzdF9sYWJlbCxrb2htYXAucHJlZGljdCRwcmVkaWN0aW9uc1tbMl1dKQpjb25mdXNpb25NYXRyaXgocHJlZGljdGlvbl90YWJsZSkKYGBgCmBgYHtyfQojIyBSRURFUwpjcmltZW4gPC0gc3Vic2V0KHdlYXBvbnNfdmlvbGF0aW9uX3RyLCBzZWxlY3Q9LWMoY2FzZV9udW1iZXIsYmxvY2ssZGF5LGxhdGl0dWRlLGxvbmdpdHVkZSkpCgpsaWJyYXJ5KGtvaG9uZW4pICMgZm9yIGJ1aWxkaW5nIHRoZSBTT00gbWFwCmxpYnJhcnkoY2FyZXQpICAgICAjZm9yIGNvbmZ1c2lvbiBtYXRyaXgKCiNFeHRyYWN0aW5nIHRhcmdldCB2YXJpYWJsZQp0YXJnZXRfdHJhaW4gPC0gY3JpbWVuJGRpc3RyaWN0CmNyaW1lbiA8LSBzdWJzZXQoY3JpbWVuLCBzZWxlY3Q9LWMoZGlzdHJpY3QpKQoKY3JpbWVuJGFycmVzdCA8LSBhcy5mYWN0b3IoY3JpbWVuJGFycmVzdCkKY3JpbWVuJGFycmVzdCA8LSBhcy5udW1lcmljKGNyaW1lbiRhcnJlc3QpCmNyaW1lbiRwcmltYXJ5X3R5cGUgPC0gYXMuZmFjdG9yKGNyaW1lbiRwcmltYXJ5X3R5cGUpCmNyaW1lbiRwcmltYXJ5X3R5cGUgPC0gYXMubnVtZXJpYyhjcmltZW4kcHJpbWFyeV90eXBlKQojbmFyY290aWNzX25uJGRpc3RyaWN0IDwtIGFzLm51bWVyaWMobmFyY290aWNzX25uJGRpc3RyaWN0KQojY2hpY2Fnb19jcmltZV9ubiRkaXN0cmljdCA8LSBhcy5mYWN0b3IoY2hpY2Fnb19jcmltZV9ubiRkaXN0cmljdCkKY3JpbWVuJGRlc2NyaXB0aW9uIDwtIGFzLmZhY3RvcihjcmltZW4kZGVzY3JpcHRpb24pCmNyaW1lbiRkZXNjcmlwdGlvbiA8LSBhcy5udW1lcmljKGNyaW1lbiRkZXNjcmlwdGlvbikKY3JpbWVuJGxvY2F0aW9uX2Rlc2NyaXB0aW9uIDwtIGFzLmZhY3RvcihjcmltZW4kbG9jYXRpb25fZGVzY3JpcHRpb24pCmNyaW1lbiRsb2NhdGlvbl9kZXNjcmlwdGlvbiA8LSBhcy5udW1lcmljKGNyaW1lbiRsb2NhdGlvbl9kZXNjcmlwdGlvbikKY3JpbWVuJG1vbnRoIDwtIGFzLm51bWVyaWMoY3JpbWVuJG1vbnRoKQoKI1NjYWxpbmcgb3JpZ2luYWwgZGF0YQpzZXQuc2VlZCg3KQojdGFyZ2V0X3RyYWluLnNjPC1zY2FsZShjaGljYWdvX2NyaW1lX25uX3RyKQojdGFyZ2V0X3Rlc3Quc2M8LXNjYWxlKGNoaWNhZ29fY3JpbWVfbm4pCgojIGNyZWF0aW9uIG9mIHRyYWluaW5nIGFuZCB0ZXN0IGRhdGFzZXRzCmluZGV4IDwtIHNhbXBsZShucm93KGNyaW1lbiksIHJvdW5kKDAuNzUqbnJvdyhjcmltZW4pKSkKdHJhaW4gPC0gY3JpbWVuW2luZGV4LF0KdGVzdCA8LSBjcmltZW5bLWluZGV4LF0KCiN0cmFpbiA8LSBjaGljYWdvX2NyaW1lX25uX3RyCnRyYWluIDwtIGFzLm1hdHJpeCh0cmFpbikKI3Rlc3QgPC0gY2hpY2Fnb19jcmltZV9ubgp0ZXN0IDwtIGFzLm1hdHJpeCh0ZXN0KQoKI3RyYWluX2xhYmVsPC10YXJnZXRfdHJhaW4KI3Rlc3RfbGFiZWw8LXRhcmdldF90ZXN0CnRyYWluX2xhYmVsPC10YXJnZXRfdHJhaW5baW5kZXhdCnRlc3RfbGFiZWw8LXRhcmdldF90cmFpblstaW5kZXhdCgojbWFpbiBjaGFyYWN0ZXJpc3RpY3Mgb2YgdGhlIG1hcApzb21fZ3JpZDwtc29tZ3JpZCh4ZGltPTEyLCB5ZGltPTEyLCB0b3BvPSJoZXhhZ29uYWwiKQoKI3RyYWluaW5nIHRoZSBtYXAKY3JpbWUuc29tIDwtIHNvbSh0cmFpbiwgZ3JpZD1zb21fZ3JpZCwgCiAgICAgICAgICAgICAgIHJsZW49MTAwLCBhbHBoYT1jKDAuMDUsIDAuMDEpLCAKICAgICAgICAgICAgICAgcmFkaXVzPSAyLCBrZWVwLmRhdGE9VCkKCiMgTmFtZXMgb2YgdGhlIHZhcmlhYmxlcyB1c2VkCmNvbG5hbWVzKHRyYWluKQoKIyBtYWluIGNoYXJhY3RlcmlzdGljcyBvZiB0aGUgbWFwCnN1bW1hcnkoY3JpbWUuc29tKQoKI1Nob3dpbmcgdGhlIHRyYWluaW5nIHByb2Nlc3MKcGxvdChjcmltZS5zb20sIHR5cGU9ImNoYW5nZXMiKQoKI25vZGUgY291bnRzCnBsb3QoY3JpbWUuc29tLCB0eXBlPSJjb3VudHMiLCBtYWluPSJFeGFtcGxlcyBwZXIgTmV1cm9uIikKCiNDb2Rlcy9XZWlnaHQgdmVjdG9ycwpwbG90KGNyaW1lLnNvbSwgdHlwZT0iY29kZXMiLCBtYWluPSJQYXR0ZXJucyBEaXNjb3ZlcmVkIikKCiNTY2FsaW5nIG9yaWdpbmFsIGRhdGEKc2V0LnNlZWQoNykKCiNtYWluIGNoYXJhY3RlcmlzdGljcyBvZiB0aGUgbWFwCnNvbV9ncmlkPC1zb21ncmlkKHhkaW09MTIsIHlkaW09MTIsIHRvcG89ImhleGFnb25hbCIpCnNldC5zZWVkKDcpCmtvaG1hcCA8LSB4eWYodHJhaW4sIHRyYWluX2xhYmVsLAogICAgICAgICAgICAgIGdyaWQ9c29tX2dyaWQsIAogICAgICAgICAgICAgIHJsZW49MTAwLCBhbHBoYT1jKDAuMDUsIDAuMDEpLCAKICAgICAgICAgICAgICByYWRpdXM9IDIsIGtlZXAuZGF0YT1UKQoKI1Nob3dpbmcgdGhlIHRyYWluaW5nIHByb2Nlc3MKcGxvdChrb2htYXAsIHR5cGU9ImNoYW5nZXMiKQoKI1Nob3dpbmcgZGlzdHJpYnV0aW9uIG9mIHdpbmUgbGFiZWxzIGluIG5ldXJvbnMKcGxvdChrb2htYXAsIHR5cGU9ImNvZGVzIiwgIGNvZGVSZW5kZXJpbmcgPSAibGluZXMiLCBzaGFwZT0ic3RyYWlnaHQiLAogICAgIG1haW49YygiQ3JpbWUiKSkKCnBsb3Qoa29obWFwLCB0eXBlPSJjb2RlcyIsICBjb2RlUmVuZGVyaW5nID0gImxpbmVzIiwgc2hhcGU9InN0cmFpZ2h0IiwKICAgICBtYWluPWMoIiBwYXR0ZXJucyIpKQoKIyBQbG90dGluZyBjbGFzc2VzIGluIG5ldXJvbnMKI3Bsb3Qoa29obWFwLCB0eXBlPSJtYXBwaW5nIiwgbGFiZWxzPWFzLm51bWVyaWModHJhaW5fbGFiZWwpKzMsCiMgICAgIGNvbD1hcy5udW1lcmljKHRyYWluX2xhYmVsKSszLCBwY2g9NCwgbWFpbj0iTWFwIG9mIGNsYXNzZXMiLCBwYWxldHRlLm5hbWUgPSB0ZXJyYWluLmNvbG9ycykKCiNQcmVkaWN0aW9uIHVzaW5nIHRoZSB0cmFpbmluZyBkYXRhCnByaW50KCJUUkFJTklORyBQUkVESUNUSU9OIikKa29obWFwLnByZWRpY3RfdHI8LSBwcmVkaWN0KGtvaG1hcCwgbmV3ZGF0YT10cmFpbiwgd2hhdG1hcCA9IDEpCnByZWRpY3Rpb25fdGFibGVfdHI8LXRhYmxlKHRyYWluX2xhYmVsLGtvaG1hcC5wcmVkaWN0X3RyJHByZWRpY3Rpb25zW1syXV0pCmNvbmZ1c2lvbk1hdHJpeChwcmVkaWN0aW9uX3RhYmxlX3RyKQoKI1ByZWRpY3Rpb24gdXNpbmcgdGhlIHRlc3QgZGF0YQpwcmludCgiVEVTVCBQUkVESUNUSU9OIikKa29obWFwLnByZWRpY3Q8LSBwcmVkaWN0KGtvaG1hcCwgbmV3ZGF0YT10ZXN0LCB3aGF0bWFwID0gMSkKcHJlZGljdGlvbl90YWJsZTwtdGFibGUodGVzdF9sYWJlbCxrb2htYXAucHJlZGljdCRwcmVkaWN0aW9uc1tbMl1dKQpjb25mdXNpb25NYXRyaXgocHJlZGljdGlvbl90YWJsZSkKYGBgCmBgYHtyfQpsaWJyYXJ5KFJDb2xvckJyZXdlcikKZ3JvdXBzPC0yMwojQXBwbHlpbmcgaGllcmFyY2hpY2FsIGNsdXN0ZXJpbmcgZm9yIGdyb3VwaW5nIHBhdHRlcm5zCmNyaW1lLmhjPWN1dHJlZShoY2x1c3QoZGlzdChjcmltZS5zb20kY29kZXNbWzFdXSkpLCBncm91cHMpCnBsb3QoY3JpbWUuc29tLCB0eXBlPSJjb2RlcyIsIGJnY29sID0gaGVhdC5jb2xvcnMoZ3JvdXBzKVtjcmltZS5oY10sCiAgICAgbWFpbj0iY2x1c3RlcmluZyB0aGUgcGF0dGVybnMgZGlzY292ZXJlZCIpCmFkZC5jbHVzdGVyLmJvdW5kYXJpZXMoY3JpbWUuc29tLGNyaW1lLmhjKQpgYGAKCgoK